如何重现ASP.NET MVC 4密码哈希

时间:2013-10-03 11:14:57

标签: sql-server asp.net-mvc-4 hash password-encryption

如何重现由内置成员资格系统生成的ASP.NET MVC 4密码哈希?

例:
输入:loz123
输出:APeJ4h0M4h7OFz91WwmJUjFfI2Daiq5xaUaZzcevoyWfkPZ3SYFJ48F + YzNrBNvaJA ==
"盐"数据库中的字段为空。

我正在将数据从一个数据库传输到另一个数据库。在源数据库中,密码存储为纯文本。在目标数据库中,密码应存储为ASP.NET成员系统生成的哈希。 我知道散列是关于使用SHA1算法和base64编码的东西,但我无法获得正确的输出。 如果MS SQL Server中有内置函数会很方便,这样就可以执行如下查询:

SELECT Username, Hash(Password) FROM Users

2 个答案:

答案 0 :(得分:2)

这可以帮助您找到正确的算法:

http://msdn.microsoft.com/en-us/library/system.web.security.sqlmembershipprovider.passwordformat.aspx

您必须检查您的具体设置。

MSDN摘要:

  

SQL Server会员提供商支持清除加密哈希密码格式。 清除密码以纯文本格式存储,这提高了密码存储和检索的性能,但安全性较低,因为如果您的SQL Server数据库受到损害,可以轻松读取密码。 加密密码在存储时会加密,并且可以解密以进行密码比较或密码检索。这需要额外的密码存储和检索处理,但更安全,因为如果SQL Server数据库受到损害,则无法轻易确定密码。 哈希密码在存储在数据库中时使用单向哈希算法和随机生成的盐值进行哈希处理。验证密码后,将使用数据库中的salt值进行哈希处理以进行验证。无法检索哈希密码。

     

PasswordFormat值在ASP.NET应用程序的Web.config文件的providers部分中指定。

     

默认情况下,加密或散列密码会根据配置中machineKey元素中提供的信息进行加密或散列。请注意,如果为验证属性指定了3DES值,或者未指定任何值,则使用SHA1算法对散列密码进行哈希处理。

     

可以使用成员资格元素(ASP.NET设置架构)配置元素的hashAlgorithmType属性定义自定义哈希算法。如果选择加密,则默认密码加密使用AES。您可以通过设置machineKey配置元素的decryption属性来更改加密算法。如果要加密密码,则必须为machineKey元素中的decryptionKey属性提供显式值。使用带有ASP.NET成员身份的加密密码时,不支持decryptionKey属性的默认值AutoGenerate。

答案 1 :(得分:0)

我不得不用“清除”密码将旧数据库更新为“哈希”,我想用sql来实现 - 这就是我想出来的,使交换变得快速而简单。

注意:先备份!!

Select * into dbo.aspnet_Membership_BACKUP from [dbo].[aspnet_Membership]

计算哈希值的函数:

/*
    Create compatible hashes for the older style ASP.Net Membership

    Credit for Base64 encode/decode: http://stackoverflow.com/questions/5082345/base64-encoding-in-sql-server-2005-t-sql
*/
Create Function dbo.AspNetHashCreate (@clearPass nvarchar(64), @encodedSalt nvarchar(64))
Returns nvarchar(128)
as
begin
    declare @binSalt varbinary(128)
    declare @binPass varbinary(128)

    declare @result nvarchar(64)

    Select @binPass = CONVERT(VARBINARY(128), @clearPass)

    --  Passed salt is Base64 so decode to bin, then we'll combine/append it with password
    Select @binSalt = CAST(N'' as XML).value('xs:base64Binary(sql:column("bin"))','VARBINARY(128)') 
        from (Select @encodedSalt as bin) as temp;

    --  Hash the salt + pass, then convert to Base64 for the output
    Select @result = CAST(N'' as XML).value('xs:base64Binary(xs:hexBinary(sql:column("bin")))', 'NVARCHAR(64)')
        from (Select HASHBYTES('SHA1', @binSalt + @binPass) as bin) as temp2;

    --  Debug, check sizes
    --Select DATALENGTH(@binSalt), DATALENGTH(@binPass), DATALENGTH(@binSalt + @binPass)

    return @result
end

这样称呼:

Update [dbo].[aspnet_Membership] set PasswordFormat = 1, Password = dbo.AspNetHashCreate(password, PasswordSalt) where PasswordFormat = 0

即使我的数据库最初设置为“清除”密码,也会为每条记录创建salt值,但是,如果由于某种原因您没有salt值,则可以使用此值创建它们:

/*
    Create compatible salts for the older style ASP.Net Membership (just a 16 byte random number in Base64)

    Note: Can't use newId() inside function so just call it like so: dbo.AspNetSaltCreate(newId())

    Credit for Base64 encode: http://stackoverflow.com/questions/5082345/base64-encoding-in-sql-server-2005-t-sql
*/
Create Function dbo.AspNetSaltCreate (@RndId uniqueidentifier)
    Returns nvarchar(24)
as
begin
    return
        (Select CAST(N'' as XML).value('xs:base64Binary(xs:hexBinary(sql:column("bin")))', 'NVARCHAR(64)')
            from (select cast(@RndId as varbinary(16)) as bin) as temp)
end

然后像这样使用它:

Update [dbo].[aspnet_Membership] set PasswordSalt = dbo.AspNetSaltCreate(newId()) where PasswordSalt = ''

请注意,您需要生成Salts FIRST,然后生成哈希值。 享受!