2017-04-08 104 views
0

我们使用PBKDF2算法散列密码,使用SecretKeyFactory.generateSecret功能,像这样:SecretKeyFactory.generateSecret与InvalidKeySpecException死在IBM的Java

final SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(algorithm); 
final PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, iterations, hashLength); 
final SecretKey secretKey = secretKeyFactory.generateSecret(keySpec); 
return secretKey.getEncoded(); 

一切似乎都做工精细,但在生产服务器上,当它在IBM的Java运行时,它死与java.security.spec.InvalidKeySpecException无法生成密钥

Caused by: java.security.spec.InvalidKeySpecException: Could not generate secret key 
    at javax.crypto.SecretKeyFactory.generateSecret(Unknown Source) 
    at our.Implementation.doHash(Hasher.java:71) 
    ... 48 more 
Caused by: java.lang.RuntimeException: Error deriving PBKDF2 keys 
    at com.ibm.crypto.provider.PBKDF2KeyImpl.a(Unknown Source) 
    at com.ibm.crypto.provider.PBKDF2KeyImpl.<init>(Unknown Source) 
    at com.ibm.crypto.provider.PBKDF2HmacSHA1Factory.engineGenerateSecret(Unknown Source) 
    ... 50 more 

我们试图改变迭代次数,生成散列的大小,T他盐的大小,但没有任何帮助。我究竟做错了什么?

回答

0

显然,看起来PBKDF2的IBM Java实现坚持密码不能为空。当它是,实现抛出一个异常。

空密码可以说是一个边缘案例,但是,第一个测试案例正是这样,所以它似乎代码根本没有工作。此外,在边缘情况下,您需要确保它永不发生(验证要求用户不要使用空密码),否则您应该优雅地处理它。

如果您确实需要支持空密码,您需要将它们作为特殊情况处理,或者只是规范化所有密码,以便输入到PBKDF2永远不会为空。但是,您必须确保您不会以这种方式危害安全。

最后,我们选择将所有密码与它们的长度作为前缀,以便即使是空密码末尾也用非空字符串表示。像这样:

final String prefixedPassword = String.format(Locale.ROOT, "%08x%s", password.length(), password);