我正在开发一个Java身份验证子系统,该子系统将数据库中的密码存储为PBKDF2-generated散列,现在我正在决定是使用SHA1还是使用SHA512作为PFR。我的印象是,大家一致认为SHA1有一些理论上的弱点,应该选择SHA512。然而,标准的javax.crypto包不提供PBKDF2WithHmacSHA512实现,这是怎么回事?
为了便于参考,下面是我的代码:
private static final int HASH_BYTE_SIZE = 64; // 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"); // this throws a NoSuchAlgorithmException if I replace with "PBKDF2WithHmacSHA512"
byte[] hash = skf.generateSecret(spec).getEncoded();
// convert hash and salt to hex and store in DB as CHAR(64)...发布于 2013-10-13 22:45:28
哈希算法的强度很重要,但在密钥派生函数中不那么重要。即使SHA-1被破坏,也不太可能影响PBKDF2的安全性。您最好使用SHA-1,并将迭代次数增加到对特定配置进行调整的级别。
如果必须的话,您可以使用Bouncy城堡来使用SHA-256创建PBKDF2的实现。该算法的内部安全性并不重要,如果您的服务器对侧通道攻击相对安全(对于PBKDF2可能是如此)。因此,使用未经认证的开源解决方案可能不会损害您的安全性。
你的努力也许最好花在别的地方。祝贺自己选择了一个相对较好的基于密码的KDF,选择了64位随机盐,使用了更高的迭代计数,然后继续前进。
注意:如果您想要防止硬件加速的攻击,您可以考虑使用scrypt而不是PBKDF2。
用于SHA-512 包含PBKDF2 2实现的OracleJDK1.8 "PBKDF2WithHmacSHA512"。这可以用于与其他系统的兼容性或完全不推荐使用SHA-1。
发布于 2015-09-08 05:53:07
简短的回答:您可以在这种情况下使用SHA1。与其使用PBKDF2,不如考虑使用SCrypt或其他时间内存算法。您需要将迭代次数提高到大约10,000,000:想想自从1990年代末在规范中发布1000次以来摩尔定律的增长。
长答案:针对SHA1的攻击是为了防止碰撞,而不是为了防止预图像或第二次预图像攻击。有关这意味着什么,请参见https://stackoverflow.com/questions/8860512/whats-the-difference-between-collision-resistance-and-preimage-resistance。对于PBKDF2来说,重要的电阻类型是预像电阻和第二预像电阻。
当用于预图像和第二预图像电阻时,SHA1提供了160个比特的安全强度。现在和中期使用160比特的安全力量是很好的。有关某个密钥大小/安全强度可用于多长时间的想法,请参见http://www.keylength.com/。
发布于 2015-09-09 11:42:40
...the标准javax.crypto包不提供PBKDF2WithHmacSHA512实现,这是怎么回事?
从Java8 8开始支持PBKDF2With,其中可以是任意数量的伪随机函数,包括HmacSHA512.
所以现在它得到了支持。
有什么想法吗?
其他人说的都是好建议。如果出于某种原因,您确实希望在标准java中将PBKDF2与HmacSHA512一起使用,则可以切换到Java8。
https://crypto.stackexchange.com/questions/11016
复制相似问题