gpt4 book ai didi

c# - RNGCryptoServiceProvider 不会为相同的 PWD、Salt、Iteration 组合生成相同的哈希值

转载 作者:太空狗 更新时间:2023-10-30 00:55:18 25 4
gpt4 key购买 nike

Oki 所以我想通过在 .Net 中附加随机盐来散列我的密码。我为此目的使用的内置类是 RNGCryptoServiceProvider - 用于生成随机盐和 Rfc2898DeriveBytes - 用于散列实际密码。

但是当我调用 Rfc2898DeriveBytes 的 GetBytes() 函数来获取 passwordString、SaltBytes 和迭代计数的相同组合时,结果是不同的。我正在粘贴我的代码以供引用

    public class PBKDF2Implementation
{
int minSaltSize = 32;
int maxSaltSize = 64;


public string CreateHash(string plainText , out string salt)
{
Random random = new Random();
int saltSize = random.Next(minSaltSize, maxSaltSize);

// Allocate a byte array, which will hold the salt.
byte[] saltBytes = new byte[saltSize];

// Initialize a random number generator.
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
// Fill the salt with cryptographically strong byte values.
rng.GetNonZeroBytes(saltBytes);

string strSalt = System.Text.Encoding.ASCII.GetString(saltBytes);
//string strSalt = System.Convert.ToBase64String(saltBytes);
salt = strSalt;

Console.WriteLine(saltBytes.Count());
Console.WriteLine(strSalt);

Rfc2898DeriveBytes pwdGen = new Rfc2898DeriveBytes(plainText, saltBytes, 1000);

// generate an RC2 key
byte[] key = pwdGen.GetBytes(32);

Console.WriteLine(System.Convert.ToBase64String(key));
return System.Convert.ToBase64String(key);
}

public bool CompareHash(string plainText, string salt, string hashValue)
{

byte[] saltBytes = System.Text.Encoding.ASCII.GetBytes(salt);
//byte[] saltBytes = System.Convert.FromBase64String(salt);

Console.WriteLine(saltBytes.Count());
Console.WriteLine(System.Text.Encoding.ASCII.GetString(saltBytes));

Rfc2898DeriveBytes pwdGen = new Rfc2898DeriveBytes(plainText, saltBytes, 1000);

// generate an RC2 key
byte[] key = pwdGen.GetBytes(32);

Console.WriteLine(System.Convert.ToBase64String(key));
return System.Convert.ToBase64String(key) == hashValue;
}
}

在我的测试课上我有这个功能

    [Test]
public void shouldGenerateConsistentHash()
{
PBKDF2Implementation cPbkdf2Implementation = new PBKDF2Implementation();
string salt;
string hashValue = cPbkdf2Implementation.CreateHash("password", out salt);

bool result = cPbkdf2Implementation.CompareHash("password", salt, hashValue);
Assert.IsTrue(result) ;
}

测试失败。
但是如果在上面的类 PBKDF2Implementation 中我替换了这些行System.Text.Encoding.ASCII.GetString 和 System.Text.Encoding.Unicode.GetString和System.Text.Encoding.ASCII.GetBytes 和 System.Text.Encoding.Unicode.GetBytes

测试通过。知道为什么会这样吗?我想让它使用 ASCII 编码的原因是因为存储这个哈希值的同一个数据库也将被 PHP 应用程序使用 & 只有当盐编码是ASCII.

这是相同的PHP实现 http://www.php.net/manual/en/function.hash-hmac.php#101540

最佳答案

  1. 避免使用加密字符串。使用字节数组,即 byte[]
  2. 如果您必须使用字符串,请非常注意编码。他们会咬你 10 次中的 9 次;

例如

byte [] data = new byte [] { 65, 0, 65 };
var s = System.Text.Encoding.ASCII.GetString (data);

什么是 s 值?

答案:“A”

如果您从同一个字符串中询问 byte[],您将得到:byte [1] { 65 },这与原始字符串不同并且不适用于大多数加密用途。

Base64 更安全,因为它会保持每个字节的完整性。

关于c# - RNGCryptoServiceProvider 不会为相同的 PWD、Salt、Iteration 组合生成相同的哈希值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10013918/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com