2

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

示例:
输入:loz123
输出:APeJ4h0M4h7OFz91WwmJUjFfI2Daiq5xaUaZzcevoyWfkPZ3SYFJ48F+YzNrBNvaJA==
数据库中的“Salt”字段为空。

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

SELECT Username, Hash(Password) FROM Users
4

2 回答 2

1

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

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

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

来自 MSDN 的总结:

SQL Server 成员资格提供程序支持ClearEncryptedHashed密码格式。明文密码以纯文本形式存储,这提高了密码存储和检索的性能,但安全性较低,因为如果您的 SQL Server 数据库遭到破坏,密码很容易被读取。加密密码在存储时被加密,并且可以被解密以进行密码比较或密码检索。这需要对密码存储和检索进行额外处理,但更安全,因为如果 SQL Server 数据库遭到破坏,则无法轻松确定密码。散列密码在存储在数据库中时使用单向哈希算法和随机生成的盐值进行哈希处理。验证密码后,将使用数据库中的盐值对其进行哈希处理以进行验证。无法检索散列密码。

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

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

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

于 2013-10-03T12:29:33.567 回答
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

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

/*
    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,然后是哈希值。享受!

于 2016-01-11T18:50:19.773 回答