7

我在 C# 中有以下代码

PasswordDeriveBytes DerivedPassword = new PasswordDeriveBytes(Password, SaltValueBytes, HashAlgorithm, PasswordIterations);
byte[] KeyBytes = DerivedPassword.GetBytes(32);

我正在使用“SHA1”散列算法。

根据 SHA1 定义,它生成 160 位(20 字节)的密钥。我的问题是 GetBytes 方法如何从 DerivedPassword 获取 32 个字节,GetBytes 方法背后使用什么算法?

4

3 回答 3

11

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

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

强烈建议您使用Rfc2898DeriveBytes自 .NET 2.0 起可用的实现 PBKDF2 (PKCS#5 v2) 的较新版本。

于 2012-02-10T19:22:34.690 回答
5

GetBytes 方法背后使用什么算法?

它使用算法 PBKDF1,稍作修改以允许任意密钥长度。一个替换类,Rfc2898DeriveBytes使用 PBKDF2。

您可以阅读有关 PBKDF2 的 Wikipedia 文章,以大致了解哪些基本概念使这项工作发挥作用。

于 2012-02-10T17:12:18.003 回答
4

密钥派生函数使用一种称为Key Stretching的功能。(不要费心在 Wikipedia 上查找它,因为当前的文章将这个概念与密钥强化混淆了,这是完全不同的东西。)

密钥拉伸通常通过在 CTR 模式下应用 PRF(例如散列函数或密码)或通过迭代它并连接中间输出来完成。

例如,如果您使用 CTR 过程,SHA-1 作为 PRF,并且想要 32 个字节的伪随机输出,您可以将 SHA1(keymaterial,0) 与 SHA1(keymaterial,1) 的前 12 个字节连接起来。

于 2012-02-10T18:47:31.993 回答