我正在集成一个新的认证rest API,这是我们的web开发团队编写的。我需要处理的最后一部分将返回用户的User_Id GUID,当给定的用户名和密码散列与存储在我们的用户数据库中的SHA1 Base64Encoded密码散列匹配时。
使用以下带有硬编码用户名和密码盐的VB.Net代码,我可以创建一个有效的密码散列。
.....
.....
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中创建相同的密码散列。
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_Hashdbo.base64_encode的函数代码如下:
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;对应的解码函数(未在示例中使用,但为了完整而包含)
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脚本不能产生相同的结果吗?
发布于 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。
--Shows the conversion from salt string back to original UNIQUEIDENTIFIER
SELECT CONVERT(UNIQUEIDENTIFIER, [dbo].[base64_decode]
('CQ4znO+Dd28GRle54xSW6A==');一旦我有了原始的UNIQUEIDENTIFIER,我就用这个值通过我之前分享的TSQL脚本对密码加盐,并使Salt值匹配。
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)))https://stackoverflow.com/questions/59254350
复制相似问题