我正在研究基于从SymmetricAlgorithm继承的类的加密功能,例如TripleDes,DES等。
基本上有两种方法可以为我的算法类PasswordDeriveBytes
和Rfc2898DeriveBytes
生成一致的密钥和IV,两者都继承自DeriveBytes抽象类。
PasswordDeriveBytes.GetBytes()
方法在.NET框架中标记为过时,建议使用Rfc2898DeriveBytes.GetBytes(),因为它与PBKDF2标准匹配。但是,根据我的测试,在Rfc2898DeriveBytes类中调用相同的GetBytes()
方法几乎比PasswordDeriveBytes
类中的方法慢15倍,这会导致意外的CPU使用率(总是高于50%)。
以下是一些测试数据:
根据测试结果,Rfc2898DeriveBytes
的不良性能在生产环境中是不可接受的。
之前有没有人注意到这个问题?任何解决方案我仍然可以使用标准的解决方案而不会达到性能?使用过时方法的任何风险(可能在将来的版本中删除)?
谢谢你们!
修改
可能我发现问题出在哪里...... PasswordDeriveBytes
的默认迭代计数是100,而Rfc2898DeriveBytes
的默认迭代计数是1000.在我将它们更改为与1000相同的数字后,执行{ {1}}只有两倍。
答案 0 :(得分:25)
他们不是一回事。
Rfc2898DeriveBytes是PBKDF2的一个实现。 PasswordDeriveBytes是PBKDF1的实现。 PBKDF2使用不同的方法生成不同的输出,并且比PBKDF1产生更多的轮数。
用于密钥派生的密码散列函数(例如这些函数)应该很慢。这就是重点 - 这使得它们更难破解。
这两个函数不兼容,而且PasswordDeriveBytes几乎不安全。
答案 1 :(得分:10)
这篇博客文章讨论了两者之间的差异:http://blogs.msdn.com/shawnfa/archive/2004/04/14/generating-a-key-from-a-password.aspx
答案 2 :(得分:10)
我认为你错过了衍生词的观点。它应该很慢。它故意使用慢速算法,这种算法无法通过聪明的技巧加速。典型的“迭代次数”参数应该在2 ^ 16-2 ^ 20范围内,并且在用户输入密码和生成密钥之间引入0.1-0.5秒的延迟。目的是防止“懒惰的无知用户”选择的弱密码,并减慢暴力搜索。