用Java中的PBKDF2进行密码验证

用Java中的PBKDF2进行密码验证,java,cryptography,passwords,aes,Java,Cryptography,Passwords,Aes,我正在用Java做基于密码的文件加密;我使用AES作为底层加密算法,并使用以下代码(我从本网站另一张慷慨的海报上获得)从salt和密码组合中派生出密钥 我共享salt,用户在每一端输入密码,加密和解密工作正常:-)我的问题是,在开始(可能很长)解密过程之前,我希望能够验证用户输入的密码是否正确。我知道PBKD规范包含可选的2字节验证值,但我不确定如何使用上述方法生成此值。Java是否对此提供了支持?如果没有,什么是安全的替代方案 谢谢您的时间。根据定义,没有安全的“快速检查”机制。使用PBKDF

我正在用Java做基于密码的文件加密;我使用AES作为底层加密算法,并使用以下代码(我从本网站另一张慷慨的海报上获得)从salt和密码组合中派生出密钥

我共享salt,用户在每一端输入密码,加密和解密工作正常:-)我的问题是,在开始(可能很长)解密过程之前,我希望能够验证用户输入的密码是否正确。我知道PBKD规范包含可选的2字节验证值,但我不确定如何使用上述方法生成此值。Java是否对此提供了支持?如果没有,什么是安全的替代方案


谢谢您的时间。

根据定义,没有安全的“快速检查”机制。使用PBKDF2或相关技术的全部目的是降低密码检查的速度,以挫败密码破解程序。如果您添加了一个快速检查系统,密码破解者将能够快速猜出大量密码。

计算某种密码验证标签,并将其与加密文件数据一起存储,以便您可以首先检查它。这可能类似于固定(短)字符串的PBMAC。当然,这需要是一个不可逆的函数,这样破解者就不能确定密码,也不能计算得太快,从而混淆暴力攻击


您是否考虑过是否(以及如何)检测整个文件是否已正确解密?您可能应该研究PBES2和PBMAC的一些组合,而不是直接使用AES。

嘿,感谢疯狂的斯科特和克里斯的帮助。在做了一些挖掘之后,我决定使用上面描述的方法进行密码验证和消息验证。我相信这种基于PBKDF2和MAC的方法,使得为m导出密码的验证值的成本足够高,从而使其安全。再次感谢,我希望此解决方案能帮助其他人。

您好,感谢您的快速响应以及您对PBES2和PMAC的建议,我将对此进行深入研究。我曾想过使用固定字符串的方法,但担心这会使过程受到已知的纯文本攻击。相反,我考虑使用密钥本身的安全散列,如果散列函数确实是不可逆的,那么这将不会提供关于密钥本身的任何信息,但仍然允许我检查密钥是否相同。你认为这是一种好方法吗?确实,某种形式的验证必然会产生某种形式的已知明文。然而,PB*函数的使用使得work函数更加困难,与一个简单的散列相比,它可以有效地乘以迭代计数。嗨,谢谢你的回答。我的印象是,PBKDF2及其反复组合salt和password来派生密钥的目的是使从纯文本密码计算密钥的过程变得昂贵,从而使字典式攻击更加困难。正如我所说的PBKDF2规范包含一个可选的密码验证值,我只是不知道如何在java实现中获得它。我同意,在密钥派生过程完成后允许快速检查使暴力攻击变得更容易,因为攻击者实际上不需要解密任何东西来检查密钥,但是我认为256位AES密钥的巨大搜索空间使得纯暴力攻击无论如何都是禁止的?@pinkynobrain:quick check的问题是它大大缩小了密钥空间:您可以快速找到快速检查成功的所有密码短语。因此,您可以使用更少的密钥对AES进行暴力攻击。
SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec ks = new PBEKeySpec(password,salt,1024,128);
SecretKey s = f.generateSecret(ks);
Key k = new SecretKeySpec(s.getEncoded(),"AES");