【发布时间】:2016-06-25 05:19:24
【问题描述】:
我使用 SHA512Managed 类对用户密码字符串进行编码。我最初按以下方式创建了标准具字符串:
- 将密码字符串(例如“Johnson_#1”)转换为字节数组;
- 使用 SHA512Managed.ComputeHash 获取此字节数组的哈希值 方法。如您所知,从 SHA512Managed.ComputeHash(byte[]) 获得的哈希值 方法也是字节数组。
然后(在程序循环中)我通过以下方式将此哈希字节数组转换为字符串:
System.Text.StringBuilder sBuilder = new System.Text.StringBuilder();
for (int i = 0; i < passwordСache.Length; i++)
{
sBuilder.Append(passwordСache[i].ToString("x2"));
}
string passwordCacheString = sBuilder.ToString();
其中 passwordСache 是哈希字节数组,passwordCacheString 是结果字符串。
最后,我将结果字符串作为标准具字符串存储在 MS SQL Server 数据库表中。
问题如下:如果我定期调用 SHA512Managed.ComputeHash(byte[]) 方法并且每次都将相同的字节数组作为输入参数传递给它(例如从“Johnson_#1”字符串获得),那么返回的哈希字节数组的内容会不时变化。
因此,如果我将此类哈希字节数组转换为字符串(如上所示)并将此字符串与数据库表中的标准具字符串进行比较,那么此字符串的内容将与标准具字符串的内容不同,尽管相同的字符串(“Johnson_#1”)是底线。
更好地定义问题
我的问题是:有没有办法确定两个具有不同内容的比较 SHA512Managed 哈希字节数组是在同一字符串的基础上创建的?我们将非常感谢您的帮助。
【问题讨论】:
-
那么返回的hash字节数组的内容会不时变化:这是绝对不可能的。哈希函数是确定性的。相同的输入 --> 相同的输出。您在其他地方犯了错误。经典错误在于您将
string转换为byte[]的方式。 -
那么结果SHA512Managed hash byte[]不能不时改变其内容,如果相同的字符串作为基础?
-
否则会完全没用。
-
参见wiki:哈希过程必须是确定性的——这意味着对于给定的输入值,它必须始终生成相同的哈希值。换句话说,在术语的数学意义上,它必须是要散列的数据的函数。此要求不包括依赖于外部变量参数的哈希函数,例如伪随机数生成器或一天中的时间......
-
不,错误出在转换
string的代码中 -->byte[],因为即使Convert.ToBase64String也是确定性的。