使用Hashbytes转换存储在SQL中的一些明文密码后,似乎无法让.Net生成正确的匹配哈希。
用于转换密码的SQL:
UPDATE Users
SET UserPassword = HASHBYTES('SHA1', UserPassword + CAST(Salt AS VARCHAR(36)))
现在用于生成哈希的.Net代码:
Dim oSHA1 As New System.Security.Cryptography.SHA1CryptoServiceProvider
Dim bValue() As Byte
Dim bHash() As Byte
bValue = System.Text.Encoding.UTF8.GetBytes(sPlainTextPass)
bHash = oSHA1.ComputeHash(bValue)
oSHA1.Clear()
Dim sEncryptPass As String = String.Empty
For i As Integer = 0 To bHash.Length - 1
sEncryptPass = sEncryptPass + bHash(i).ToString("x2").ToLower()
Next
补充说明:盐存储在数据库中。 sPlainTextPass包含纯文本密码+ salt。我尝试了几种不同的编码,包括ASCII,UTF7和UTF8。数据库字段是一个varchar,应该根据我的理解与UTF8匹配。
帮助?
答案 0 :(得分:2)
您不能散列字符串,只能散列字节。因此,SQL Server和您必须使用编码将字符串转换为字节。
SQL Server不支持UTF8。您需要找出它的用途并在您的应用程序中匹配该编码。对于nvarchar,我会尝试Encoding.Unicode
并使用稀有和特殊字符对其进行测试。
网上似乎有一些关于这个主题的信息,我发现谷歌搜索“哈希字节编码”:http://weblogs.sqlteam.com/mladenp/archive/2009/04/28/Comparing-SQL-Server-HASHBYTES-function-and-.Net-hashing.aspx虽然我必须说博客帖子包含明显的错误而且不可信任。
答案 1 :(得分:0)
我之前看到过这种事情发生在Sybase SQLAnywhere上。根据您正在使用的SQL数据库,它可能会自己填充哈希值,在这种情况下,您永远不会得到匹配的哈希值(不知道数据库的内部工作方式,即)
编辑:
如果您想要比较密码,根据任何内部盐析,您可以将.NET散列密码发送到数据库,在那里再次哈希,并检查与存储值的相等性。这当然假设您以类似的方式存储了密码。
答案 2 :(得分:0)
在T-SQL中使用nvarchar类型而不是varchar,结果也将匹配
答案 3 :(得分:0)
我经历过同样的事情...... 我认为它与update语句有关,以便在users表中填充哈希值。
我发现问题是数据类型。如果在表达式中
UserPassword + CAST(Salt AS VARCHAR(36))
UserPassword列是nvarchar,结果将是nvarchar和不同的哈希。
我通过强制转换表达式将密码和salt连接到varchar来解决我的问题。
一个很好的测试,看看这是否真的是同样的问题是运行这个......
SELECT HASHBYTES('SHA1', UserPassword + CAST(Salt AS VARCHAR(36))),
HASHBYTES('SHA1', CAST( UserPassword + CAST(Salt AS VARCHAR(36))as varchar))
FROM Users