我正在开发一个 Java 身份验证子系统,它将数据库中的密码存储指定为 PBKDF2
生成的哈希值,我现在正在尝试决定是否应该使用 SHA1
或 SHA512
作为 PRF。我浏览了两者的规范,但它们在数学上对我来说非常密集。有更好的加密理解的人可以解释 PBKDF2WithHmacSHA512
与 PBKDF2WithHmacSHA1
有何不同吗?
这是我想要做的:
private static final int HASH_BYTE_SIZE = 64 * 8; // 512 bits
private static final int PBKDF2_ITERATIONS = 1000;
// generate random salt
SecureRandom random = new SecureRandom();
byte salt[] = new byte[SALT_BYTE_SIZE]; // use salt size at least as long as hash
random.nextBytes(salt);
// generate Hash
PBEKeySpec spec = new PBEKeySpec(password, salt, PBKDF2_ITERATIONS, HASH_BYTE_SIZE);
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); // we would like this to be "PBKDF2WithHmacSHA512" instead? What Provider implements it?
byte[] hash = skf.generateSecret(spec).getEncoded();
// convert hash and salt to hex and store in DB as CHAR(64)...
最佳答案
让我们逐个分解单词:
PBKDF2--WithHmac--SHA512
让我们一步一步地回顾它
-
代表 Password-based-Key-Derivative-Function,是 PBKDF1 的继承者,用于实现伪随机函数,例如输入密码或密码短语的加密哈希、密码或 HMAC 以及盐值和多次重复该过程以生成派生 key ,然后可以将其用作后续操作中的加密 key 。
HMAC
Keyed-Hash Message Authentication Code (HMAC) 是一种用于计算消息认证码 (MAC) 的特定结构,其中涉及加密散列函数与 key 的组合。任何密码散列函数,可用于计算 HMAC;生成的 MAC 算法相应地称为 HMAC-MD5 或 HMAC-SHA1。
SHA512
嗯,你知道的.. :P
现在,回到你的问题,代码行:
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
指定 keyFactory 使用算法 PDBKDF2WithHmacSHA1
。当你会做类似的事情时:
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");
你告诉工厂使用算法PBDKF2WithHmacSHA512
。
PBKDF2WithHmacSHA1
和 PBKDF2WithHmacSHA512
的主要区别在于:
PBKDF2WithHmacSHA1
将产生 160 位的哈希长度。PBKDF2WithHmacSHA512
将产生 512 位的哈希长度。
因此后者更安全。但双方都存在关于哪些足以加密的争论。没有辩论。只是说说而已。
关于这两种算法的一些附加信息:
HMACSHA1
HMACSHA1 is a type of keyed hash algorithm that is constructed from the SHA1 hash function and used as an HMAC, or hash-based message authentication code. The HMAC process mixes a secret key with the message data, hashes the result with the hash function, mixes that hash value with the secret key again, and then applies the hash function a second time. The output hash is 160 bits in length.
HMACSHA512
HMACSHA512 is a type of keyed hash algorithm that is constructed from the SHA-512 hash function and used as a Hash-based Message Authentication Code (HMAC). The HMAC process mixes a secret key with the message data and hashes the result. The hash value is mixed with the secret key again, and then hashed a second time. The output hash is 512 bits in length.
主要优点是 HmacWith512
比 HmacWith256
更安全。例如
HMAC_SHA1("key","The quick brown fox jumps over the lazy dog") = 0xde7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9
HMAC_SHA512("key","The quick brown fox jumps over the lazy dog") = 0xb42af09057bac1e2d41708e48a902e09b5ff7f12ab428a4fe86653c73dd248fb82f948a549f7b791a5b41915ee4d1ec3935357e4e2317250d0372afa2ebeeb3a
差异非常大(如图所示)。希望能帮助到你。 :)
编辑:正如 OP 提到的
PBEKeySpec(char[] password, byte[] salt, int iterationCount, int keyLength)
参数keyLength
用于表示对 key 长度的偏好
用于可变 key 大小的密码。实际的 key 大小取决于每个提供者的实现。因此说,做类似的事情
PBEKeySpec(password, salt, int 100, 512)
并不意味着您将使用 SHA1 来生成 512 的 keyLength。它只是意味着。 SHA1 最多支持 160 位。你不能超过那个。
关于第二个问题,请看HMAC-SHA1 .有许多声明说,如果您使用长散列,像 SHA256
这样的算法非常好。
另外,根据美国国家安全局:
The NSA specifies that "Elliptic Curve Public Key Cryptography using the 256-bit prime modulus elliptic curve as specified in FIPS-186-2 and SHA-256 are appropriate for protecting classified information up to the SECRET level. Use of the 384-bit prime modulus elliptic curve and SHA-384 are necessary for the protection of TOP SECRET information.
我认为将 HMAC 函数与 SHA512 结合使用是非常安全的。
关于java - PBKDF2WithHmacSHA512 对比。 PBKDF2WithHmacSHA1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19348501/