4

在使用 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 包含纯文本的密码+盐。我尝试了几种不同的编码,包括 ASCII、UTF7 和 UTF8。数据库字段是一个 varchar,据我了解,它应该与 UTF8 匹配。

帮助?

4

4 回答 4

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虽然我必须说这篇博文包含明显的错误,不能被信任。

于 2012-06-28T13:11:13.067 回答
0

我曾在 Sybase SQLAnywhere 中看到过这种情况。根据您使用的 SQL 数据库,它可能会自行对哈希进行加盐,在这种情况下,您永远不会得到匹配的哈希(即不知道数据库的内部工作原理)

编辑:

如果您要比较密码,考虑到任何内部加盐,您可以将 .NET 散列密码发送到数据库,在那里再次对其进行散列,并检查与存储值是否相等。这当然假设您以类似的方式存储了密码。

于 2012-06-27T19:18:35.377 回答
0

在 T-SQL 中使用 nvarchar 类型而不是 varchar 并且结果也将匹配

于 2012-11-07T19:05:14.233 回答
0

我经历过同样的事情......我认为它与更新语句有关,以便将您的哈希填充到用户表中。

我发现问题出在数据类型上。如果在表达式中

UserPassword + CAST(Salt AS VARCHAR(36))

UserPassword 列是 nvarchar,结果将是 nvarchar 和不同的哈希值。

我通过将表达式转换为将密码和盐连接到 varchar 来解决我的问题。

一个很好的测试,看看这是否真的是同一个问题是通过运行这个......

SELECT HASHBYTES('SHA1', UserPassword + CAST(Salt AS VARCHAR(36))),
HASHBYTES('SHA1', CAST( UserPassword + CAST(Salt AS VARCHAR(36))as varchar)) 
FROM Users
于 2014-03-28T16:45:54.763 回答