首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SQL HashBytes vs .Net HashAlgorithm

SQL HashBytes vs .Net HashAlgorithm
EN

Stack Overflow用户
提问于 2019-12-10 02:05:27
回答 1查看 315关注 0票数 1

我正在集成一个新的认证rest API,这是我们的web开发团队编写的。我需要处理的最后一部分将返回用户的User_Id GUID,当给定的用户名和密码散列与存储在我们的用户数据库中的SHA1 Base64Encoded密码散列匹配时。

使用以下带有硬编码用户名和密码盐的VB.Net代码,我可以创建一个有效的密码散列。

代码语言:javascript
复制
.....
.....
Dim passwordHash As String = EncodePassword("Testing1234", "CQ4znO+Dd28GRle54xSW6A==")

Public Function EncodePassword(ByVal pass As String, ByVal saltBase64 As String) As String
    Dim bytes As Byte() = Encoding.Unicode.GetBytes(pass)
    Dim src As Byte() = Convert.FromBase64String(saltBase64)
    Dim dst As Byte() = New Byte(src.Length + bytes.Length - 1) {}
    Buffer.BlockCopy(src, 0, dst, 0, src.Length)
    Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length)
    Dim algorithm As HashAlgorithm = HashAlgorithm.Create("SHA1")
    Dim inArray As Byte() = algorithm.ComputeHash(dst)
    Dim passwordHash AS String = Convert.ToBase64String(inArray)
    Return passwordHash
End Function

但是,我不能使用以下代码在SQL中创建相同的密码散列。

代码语言:javascript
复制
DECLARE @newPassword NVARCHAR(128) = 'Testing1234'
DECLARE @encoded_salt NVARCHAR(128) = 'CQ4znO+Dd28GRle54xSW6A=='
DECLARE @encoded_hashed_password NVARCHAR(128) = dbo.base64_encode(HASHBYTES('SHA1',
                                                     CONVERT(VARBINARY(MAX), @encoded_salt)
                                                     + CONVERT(VARBINARY(MAX), @newPassword)))
SELECT @encoded_hashed_password AS Password_Hash

dbo.base64_encode的函数代码如下:

代码语言:javascript
复制
ALTER FUNCTION [dbo].[base64_encode] (@data VARBINARY(MAX))
RETURNS VARCHAR(MAX)
WITH SCHEMABINDING,
RETURNS NULL  ON NULL INPUT
BEGIN
    RETURN (SELECT [text()] = @data FOR XML PATH(''));
END;

对应的解码函数(未在示例中使用,但为了完整而包含)

代码语言:javascript
复制
ALTER FUNCTION [dbo].[base64_decode] (@base64_text VARCHAR(MAX))
RETURNS VARBINARY(MAX)
WITH SCHEMABINDING,
RETURNS NULL ON NULL INPUT
BEGIN
    DECLARE @x XML;
    SET @x = @base64_text; 
    RETURN @x.[value]('(/)[1]', 'VARBINARY(max)');
END;

有人能帮我弄清楚为什么在我看来等同于VB.Net代码的SQL脚本不能产生相同的结果吗?

EN

回答 1

Stack Overflow用户

发布于 2019-12-10 22:24:21

在我发布这个问题几个小时后,我终于让它工作了,并认为我可以为任何未来遇到这篇文章的读者提供一个更新。

我之前分享的encode/decode函数正在工作。我分享的T-SQL脚本也在运行,但我使用了错误的Salt值。我最终发现,存储在aspnet_membership表中的Salt值实际上并不是用来对密码进行加密的。实际上,用作盐的值是通过调用NEWID()生成的UNIQUEIDENTIFIER。我共享的Salt值("CQ4znO+Dd28GRle54xSW6A==")实际上是UNIQUEIDENTIFIER的base64表示,用于对密码“加盐”。弄清楚这一点后,我可以使用之前共享的base64_decode函数将base64字符串解码为它的VARCHAR表示,然后将VARCHAR值转换回原始的UNIQUEIDENTIFIER。

代码语言:javascript
复制
  --Shows the conversion from salt string back to original UNIQUEIDENTIFIER
  SELECT CONVERT(UNIQUEIDENTIFIER, [dbo].[base64_decode]  
  ('CQ4znO+Dd28GRle54xSW6A==');

一旦我有了原始的UNIQUEIDENTIFIER,我就用这个值通过我之前分享的TSQL脚本对密码加盐,并使Salt值匹配。

代码语言:javascript
复制
 DECLARE @salt UNIQUEIDENTIFIER = NEWID()
 DECLARE @encoded_salt NVARCHAR(128) = dbo.base64_encode(@salt)
 DECLARE @encoded_hashed_password NVARCHAR(128) = dbo.base64_encode(HASHBYTES('SHA1',
                                                      CONVERT(VARBINARY(MAX), @salt)
                                                      + CONVERT(VARBINARY(MAX), 
                                                      @NewPassword)))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59254350

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档