11

我试图理解一些 C# 代码,我已经收到了,它处理密码学,特别PasswordDeriveBytes是从System.Security.Cryptography.

.NET 文档中,它说PasswordDeriveBytes使用“​​PBKDF1 算法的扩展”,该算法稍后在文档中指定为“PKCS#5 v2.0 标准”,即 PBKDF2(据我所知)。但是,我在网上找到的任何地方(包括 Stack Exchange 上的此处)都说“使用 Rfc2898DeriveBytes,因为不推荐使用 Password* 并使用 PBKDF1”。但在msdn.microsoft.com上的文档中唯一的区别似乎是 Rfc*-version 特别提到了 PBKDF2,其中 Password* 表示“PBKDF1 的扩展”和“PKCS#5 v 2.0”。

那么,谁能告诉我这两个类(如果有的话)有什么区别以及为什么我应该使用一个而不是另一个来推导 PBKDF2 密码密钥?

现在,处理相同数据的其他代码明确使用 PBKDF2,并且可以工作,因此这表明确实PasswordDeriveBytes也使用 PBKDF2,或者 PBKDF2 在某些情况下只是与 PBKDF1 兼容,但我想确定它是不是一些随机事物的副作用,而且事情只是神奇地起作用(最终可能会神奇而壮观地破坏),而没有人真正理解为什么。

4

4 回答 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)与. 与 PasswordDeriveBytes 不同,这在 Rfc2898DeriveBytes 中可以正常工作。GetBytes(3)GetBytes(8)


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 的人)。

于 2017-06-12T17:37:21.013 回答
2

我认为在这里可以找到一个很好的答案:

C# PasswordDeriveBytes 混淆

但总结一下:

Microsoft 对原始 PKCS#5(又名 PBKDF1)的实现包括不安全的扩展,以提供比散列函数所能提供的更多的字节(请参阅此处和此处的错误报告)。

即使它不是错误的,您也应该避免对标准进行未记录的专有扩展(或者您将来可能永远无法解密您的数据 - 至少不能在 Windows 之外。)

我强烈建议您使用更新的 Rfc2898DeriveBytes,它实现了自 .NET 2.0 起可用的 PBKDF2 (PKCS#5 v2)。

于 2015-01-30T13:57:20.480 回答
1

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

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

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

于 2011-08-17T18:58:20.607 回答
0

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

于 2011-08-17T15:06:13.340 回答