.NET:PasswordDeriveBytes和Rfc2898DeriveBytes之间的区别

11
我正试图理解一些与密码学有关的C#代码,它特别使用了System.Security.Cryptography中的PasswordDeriveBytes。在.NET文档中指出PasswordDeriveBytes使用“PBKDF1算法的一种扩展”,该文档稍后具体说明了这是“PKCS#5 v2.0标准”,即PBKDF2(就我而言)。
然而,在网络上找到的每个地方(包括Stack Exchange上),每个人都说“使用Rfc2898DeriveBytes,因为Password *已被弃用并使用了PBKDF1”。但是,在msdn.microsoft.com的文档中,两个类之间唯一的区别似乎是Rfc *-版本明确提到了PBKDF2,而Password *则表示“PBKDF1的扩展”和“PKCS#5 v2.0”。
那么,有人可以告诉我这两个类之间的区别(如果有的话),以及为什么我应该在PBKDF2密码密钥派生方面使用其中一个而不是另一个?
现在,处理相同数据的其他代码明确使用了PBKDF2,并且有效,因此这表明PasswordDeriveBytes也使用了PBKDF2,或者在某些情况下PBKDF2与PBKDF1兼容,但我想确保不是某些随机事物的副作用,并且事情只是神奇地工作着(最终可能会以神奇和壮观的方式破裂),而没有人真正理解为什么。
4个回答

3
如果您实例化了PasswordDeriveBytes并且只调用一次GetBytes方法,传递一个小于基础哈希算法输出大小的值,那么您将从PBKDF1算法中获得一个值。
如果您为同一个对象调用两次GetBytes,则可能会遇到计数错误的情况。
PBKDF1仅描述了最多可以输出哈希算法的大小(例如SHA-1的20个字节),但PasswordDeriveBytes类已经制定了一个公式,支持高达哈希输出大小的1000倍。因此,这个类生成的大值可能在另一个平台上难以实现。
如果您实例化Rfc2898DeriveBytes,则会得到PBKDF2算法的流式实现。PBKDF2与PBKDF1最明显的区别是PBKDF2允许生成任意量的数据(限制为(2^32-1)*hashOutputSize;或对于SHA-1而言为85,899,345,900字节)。PBKDF2还使用更复杂的构造(特别是HMAC覆盖直接哈希)使从输出值中恢复输入密码更加困难。
实现中的“流式”是指GetBytes(5)GetBytes(3)的连接与GetBytes(8)相同。与PasswordDeriveBytes不同,这在Rfc2898DeriveBytes中可以正常工作。

PBKDF1最初是为生成DES密钥而创建的,于1993年在PKCS #5 v1.5中发布。 PBKDF2于1999年在PKCS #5 v2.0中发布(后来作为RFC2898重新发布)。幻灯片演示文稿应该可以在ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-5v2/pkcs5v2-0.pdf找到(但似乎存在问题,因此可能需要使用ftp://ftp.dfn-cert.de/pub/pca/docs/PKCS/ftp.rsa.com/99workshop/pkcs5_v2.0.ppt)。幻灯片演示文稿由RSA Security撰写,他们是PBKDF1和PBKDF2的创造者,并且建议使用PBKDF2而不是PBKDF1。


2
我认为这里可以找到一个很好的答案:C# PasswordDeriveBytes Confusion 总结一下:
Microsoft对原始PKCS#5(又称PBKDF1)的实现包括不安全的扩展,以提供比哈希函数更多的字节(请参见此处和此处的错误报告)。
即使没有漏洞,您也应避免使用未经记录的专有标准扩展(否则您可能永远无法解密数据 - 至少在Windows之外)。
我强烈建议您使用较新的Rfc2898DeriveBytes,它实现了自.NET 2.0以来可用的PBKDF2(PKCS#5 v2)。

1
这是一篇详细介绍差异的博客文章:

http://blogs.msdn.com/b/shawnfa/archive/2004/04/14/generating-a-key-from-a-password.aspx

PBKDF2 可用于生成任意长度的密钥,这对基于密码的加密非常有用(它可以根据对称密码所需生成任何密钥长度),但对于安全密码存储来说意义不大。它还使用 HMAC 而不是像 PBKDF1 那样进行连接来应用盐,这在弱盐情况下具有更好的安全性能。


是的,我不是在问1和2之间的区别,而是在问两个特定的.NET类之间的区别。 :) - adamski
其中一个实现了1,而另一个实现了2 :) - orip
1
那么什么是“扩展”? - adamski

0

PKCS#5 v2.0 定义了 PBKDF1 和 PBKDF2 两种算法,前者是为了向后兼容而保留的,同时建议新应用使用 PBKDF2。我不知道为什么后者比前者更好,但是这两个 .NET 类似乎使用不同但可互操作的算法。(可能是因为只交换了结果密钥,而不是输入 + KDF。)


不一定,您仍然可以包括输出数据使用的加密方案/ KDF以及您提到的“其他代码”是在确定加密方案使用PBKDF2之后使用的代码路径。仅从“明确使用PBKDF2”无法确定。 - millimoose

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接