Web*_*ude 5 cryptography sha1 .net-4.0
我目前正在尝试将我的项目从.NET 3.5升级到.NET 4.0
一切都很顺利,所有代码都编译好,所有测试都通过了.
然后我遇到了部署到我的暂存环境的问题.
突然,我的登录不再有效.
在.NET 4中,我的SHA1哈希密码似乎有所不同.
我正在使用SHA1CryptoServiceProvider:
SHA1CryptoServiceProvidercryptoTransformSHA1 = new SHA1CryptoServiceProvider();
Run Code Online (Sandbox Code Playgroud)
为了测试我创建了一个带有2个控制台应用程序的新Visual Studio项目.
第一个针对.NET Framework 3.5,第二个针对4.0.
我在两者中都运行了完全相同的散列代码,并生成了不同的结果.
为什么会发生这种情况?我该如何解决这个问题?
我显然无法更新所有用户密码,因为我不知道它们是什么.
任何帮助将不胜感激.
代码示例
public static class SHA1Hash
{
public static string Hash(string stringToHash)
{
return (Hash(stringToHash, Encoding.Default));
}
public static string Hash(string stringToHash, Encoding enc)
{
byte[] buffer = enc.GetBytes(stringToHash + stringToHash.Reverse());
var cryptoTransformSHA1 = new SHA1CryptoServiceProvider();
string hash = BitConverter.ToString(cryptoTransformSHA1.ComputeHash(buffer));
return hash;
}
}
Run Code Online (Sandbox Code Playgroud)
其中一条评论让我发现了代码中的错误。
当创建要散列的字节数组时,我试图在字符串后面附加其自身的反向版本。
例如,给定“密码”进行散列,我实际上会散列“passworddrowssap”
但是我的代码有一个小错误:
byte[] buffer = enc.GetBytes(stringToHash + stringToHash.Reverse());
Run Code Online (Sandbox Code Playgroud)
.Reverse() 是一种可以反转字符串的 Linq 扩展方法。
但是它不返回字符串,而是返回:
IEnumerable<Char>
Run Code Online (Sandbox Code Playgroud)
在此类型上调用 .ToString() 实际上返回:
System.Linq.Enumerable+d__99`1[System.Char]
在 .NET 4.0 中执行相同的操作会返回
System.Linq.Enumerable+d__a0`1[System.Char]
因此,我的密码的哈希值不同。
我应该做的通过字节数组创建的是:
byte[] buffer = enc.GetBytes(stringToHash + new String(stringToHash.Reverse().ToArray()));
Run Code Online (Sandbox Code Playgroud)