【问题标题】:.Net SHA1CryptoServiceProvider not matching SQL Hashbytes.Net SHA1CryptoServiceProvider 不匹配 SQL Hashbytes
【发布时间】:2012-06-27 19:13:17
【问题描述】:

在使用 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 匹配。

帮助?

【问题讨论】:

  • 请不要使用单次迭代 SHA1 进行密码散列。使用 PBKDF2、bcrypt 或 scrypt。
  • 你为什么要在数据库中散列?我会在应用程序中进行所有哈希处理。
  • sPlainTextPass 包含什么?顾名思义,纯密码?在这种情况下,问题很明显:您需要在哈希中包含盐。
  • 所以基本上:您需要确保散列相同的值(以字节为单位),并且输出的编码类似。因此,您需要使用相同的(字符)编码同时输入密码盐。
  • 编辑了原始消息以回答几个问题 Faber 和 owlstead,因为我意识到他们对原始问题很重要。

标签: .net sql vb.net cryptography sha1


【解决方案1】:

您不能对字符串进行哈希处理,只能对字节进行哈希处理。因此,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 虽然我必须说这篇博文包含明显的错误并且不可信。

【讨论】:

  • 谢谢,实际上我最初是在尝试解决问题时发现该帖子的。当我再次有机会时,我会考虑在散列之前将 SQL 字符串转换为字节。我会让你知道结果如何。
【解决方案2】:

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

编辑:

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

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

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-09
        • 1970-01-01
        • 2011-10-18
        • 1970-01-01
        • 1970-01-01
        • 2021-01-05
        • 1970-01-01
        • 2018-03-05
        相关资源
        最近更新 更多