PasswordDeriveBytes vs Rfc2898DeriveBytes,过时但速度更快

tsh*_*hao 17 .net cryptography pbkdf2 rfc2898

我正在研究基于从SymmetricAlgorithm继承的类的加密功能,例如TripleDes,DES等.

基本上有两种方法可以为我的算法类生成一致的密钥和IV,PasswordDeriveBytes并且Rfc2898DeriveBytes都继承自DeriveBytes抽象类.

PasswordDeriveBytes.GetBytes()方法在.NET框架中标记为过时,建议使用Rfc2898DeriveBytes.GetBytes(),因为它与PBKDF2标准匹配.但是,根据我的测试,GetBytes()在Rfc2898DeriveBytes类中调用相同的方法几乎比类中的方法慢15倍PasswordDeriveBytes,这导致意外的CPU使用率(总是高于50%).

这是一些测试数据:

  • 迭代次数:100
  • 算法类型:DES
  • 原文:"我是测试密钥,请加密我"
  • 时间:
    • PasswordDeriveBytes:99ms
    • Rfc2898DeriveBytes:1,373ms

基于测试,Rfc2898DeriveBytes在生产环境中不良性能是不可接受的.

之前有没有人注意到这个问题?任何解决方案我仍然可以使用标准的解决方案而不会达到性能?使用过时方法的任何风险(可能在将来的版本中删除)?

多谢你们!

编辑:

可能我发现问题出在哪里...默认的迭代计数数为PasswordDeriveBytes100,而for Rfc2898DeriveBytes为1000.在我将它们更改为与1000相同的数字后,执行Rfc2898DeriveBytes只有两倍.

Bla*_*ura 26

他们不是一回事.

Rfc2898DeriveBytes是PBKDF2的实现.PasswordDeriveBytes是PBKDF1的实现.PBKDF2使用不同的方法生成不同的输出,并且比PBKDF1产生更多的轮次.

用于密钥派生的密码散列函数(例如这些函数)应该很慢.这就是重点 - 这使得它们更难破解.

这两个函数不兼容,PasswordDeriveBytes几乎不安全.

  • 通常,您只想使用这些函数从密码生成密钥.通常用于类似密码保护的存档或类似的存档.要加密存档,您将生成随机IV,并从密码和IV生成密钥.你存储了IV(但从来没有关键).然后,只要每个文件使用不同的IV(也存储在存档中)加密,您就可以为存档中的每个文件重复使用该密钥.这些功能的唯一其他用途是密码散列.当用户登录时,你会这样做一次.对于任何其他用途,可能有更好的方法. (4认同)

小智 10

我认为你错过了衍生词的观点.它应该很慢.它故意使用慢速算法,这种算法无法通过巧妙的技巧加速.典型的"迭代次数"参数应该在2 ^ 16-2 ^ 20范围内,并且在用户输入密码和生成密钥之间引入0.1-0.5秒的延迟.目的是防止"懒惰的无知用户"选择的弱密码并减慢暴力搜索.