gpt4 book ai didi

java - 如何在java中使用 key 接口(interface)作为 key ?

转载 作者:行者123 更新时间:2023-12-02 12:25:30 24 4
gpt4 key购买 nike

我有一个来自creating base 64 hashes的代码

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;

public class ApiSecurityExample {
public static void main(String[] args) {
try {
String secret = "secret";
String message = "Message";

Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
sha256_HMAC.init(secret_key);

String hash = Base64.encodeBase64String(sha256_HMAC.doFinal(message.getBytes()));
System.out.println(hash);
}
catch (Exception e){
System.out.println("Error");
}
}
}

secret_keysha256_HMAC.init(secret_key);

当我阅读时,它告诉 use Key key一个接口(interface)。

如何使用?

最佳答案

这个例子做错了,因为字符串不应该用来存储键。

key 应由对手无法预测的字节组成。生成这些数据的最合乎逻辑的方法是使用随机数生成器,但您也可以通过 key 建立 (Diffie-Hellman)、使用另一个 key 上的 key 派生函数、棘轮和许多其他方式来生成它们。

一种有点危险的方法是从密码生成它们。为此,您通常使用基于密码的 key 派生函数或 PBKDF。 Java 直接支持 PBKDF2,可用于此目的。

<小时/>

因此您可以通过以下方式创建 HMAC key :

Mac mac = Mac.getInstance("HMACSHA256");

SecureRandom rng = new SecureRandom();
// key size can be anything but should default to the hash / MAC output size for HMAC
byte[] hmacKeyData = new byte[mac.getMacLength()];
rng.nextBytes(hmacKeyData);
SecretKey hmacKey = new SecretKeySpec(hmacKeyData, "HMACSHA256");
Arrays.fill(hmacKeyData, (byte) 0x00);

但是,以下代码更短,可能更具描述性。它还允许稍后使用硬件设备来实现 Mac ,尽管这可能有点超出您的范围。

KeyGenerator kg = KeyGenerator.getInstance("HMACSHA256");
SecretKey hmacKey = kg.generateKey();

最后,如果您仍然想使用密码,请使用 PKBDF2 并且不要忘记存储盐:

// you don't want to use a string, as you cannot delete strings in Java
char[] password = {'p', 'a', 's', 's' };
SecureRandom rng = new SecureRandom();
byte[] salt = new byte[128 / Byte.SIZE];
rng.nextBytes(salt);
int iterations = 1_000_000;

Mac mac = Mac.getInstance("HMACSHA256");

PBEKeySpec spec = new PBEKeySpec(password, salt, iterations, mac.getMacLength() * Byte.SIZE);
SecretKeyFactory pbkdf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
byte[] hmacKeyData = pbkdf.generateSecret(spec).getEncoded();
SecretKey hmacKey = new SecretKeySpec(hmacKeyData, "HMACSHA256");

// clean up secret material
Arrays.fill(password, (char) 0x0000);
spec.clearPassword();
Arrays.fill(hmacKeyData, (byte) 0x00);

由于攻击者可能需要永远尝试密码(如果他有 MAC 来比较结果),因此选择一个非常复杂的密码将是一个非常好的主意;这就是为什么基于密码的加密通常不是一个好主意。

<小时/>

Key是用于 SecretKey 的通用父接口(interface), PublicKeyPrivateKey 。它被用在许多代表加密算法的类中,因为它们可以与任何类型的 key 一起使用。例如Cipher可用于 RSA,也可用于 AES。因此,该实现只是在运行时检查是否给出了正确的 key 。

对于Mac也可能是SecretKey作为Mac实际上始终是对称算法(Mac 的非对称形式毕竟称为 Signature)。不过,仅 HMAC key 是不够的,因为还有 Mac基于分组密码的算法,例如 AES(因此需要 SecretKey 和算法 "AES" )。

为了方便起见,SecretKeySpec还实现 SecretKey ;这样你就不需要 SecretKeyFactory创建 SecretKey 。 Java 设计者有点忘记了确实需要的硬件支持,例如工厂,但我们来了。

关于java - 如何在java中使用 key 接口(interface)作为 key ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59133672/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com