Asp.net
在純 T-SQL 中生成 ASP.Net Membership 密碼雜湊
我正在嘗試在 ASP.Net Membership 系統中創建預設 SHA-1 密碼散列的純 t-sql 表示。理想情況下,我會得到這樣的:
UserName Password GeneratedPassword cbehrens 34098kw4D+FKJ== 34098kw4D+FKJ==注意:那是虛假的 base-64 文本。我有正確往返的 base64_encode 和解碼函式。這是我的嘗試,它不起作用:
SELECT UserName, Password, dbo.base64_encode(HASHBYTES('SHA1', dbo.base64_decode(PasswordSalt) + 'test')) As TestPassword FROM aspnet_Users U JOIN aspnet_membership M ON U.UserID = M.UserID我在主題上嘗試了許多變體,但無濟於事。我需要在純 T-Sql 中執行此操作;涉及控制台應用程序或類似的東西將使工作加倍。
因此,如果任何人都可以提供從 ASP.Net 會員資料中複製該密碼的確切語法,我將不勝感激。
OP 請求“純”sql - 我認為使用 CLR 是作弊;)我很固執,必須自己弄清楚,所以這就是我所做的。
注意:先備份!!
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 = ''享受!
我通過從此處 ASP.NET Identity 預設密碼雜湊器對 C# 程式碼進行逆向工程來編寫雜湊儲存過程,它是如何工作的,它是否安全?還有一些很棒的 PBKDF2 SQL 函式 PBKDF2有 SQL 實現嗎?
首先創建這兩個函式取自Is there a SQL implementation of PBKDF2?
create FUNCTION [dbo].[fn_HMAC] ( @hash_algorithm varchar(25), @key VARCHAR(MAX), @message VARCHAR(MAX) ) RETURNS VARCHAR(MAX) AS BEGIN --HASH key if longer than 16 characters IF(LEN(@key) >64) SET @key = HASHBYTES(@hash_algorithm,@key) DECLARE @i_key_pad VARCHAR(MAX), @o_key_pad VARCHAR(MAX), @position INT SET @position = 1 SET @i_key_pad = '' SET @o_key_pad = '' --splice ipad & opod with key WHILE @position <= LEN(@key) BEGIN SET @i_key_pad = @i_key_pad + CHAR(ASCII(SUBSTRING(@key, @position, 1)) ^ 54) SET @o_key_pad = @o_key_pad + CHAR(ASCII(SUBSTRING(@key, @position, 1)) ^ 92) SET @position = @position + 1 END --pad i_key_pad & o_key_pad SET @i_key_pad = LEFT(@i_key_pad + REPLICATE('6',64),64) SET @o_key_pad = LEFT(@o_key_pad + REPLICATE('\',64),64) RETURN HASHBYTES(@hash_algorithm,CONVERT(VARBINARY(MAX),@o_key_pad) + HASHBYTES(@hash_algorithm,@i_key_pad + @message)) END GO和
CREATE function [dbo].[fn_PBKDF2] ( @hash_algorithm varchar(25), @password varchar(max), @salt varchar(max), @rounds int, @outputbytes int ) returns varchar(max) as begin declare @hlen int select @hlen = len(HASHBYTES(@hash_algorithm, 'test')) declare @l int SET @l = (@outputbytes +@hLen -1)/@hLen declare @r int SET @r = @outputbytes - (@l - 1) * @hLen declare @t varchar(max), @u varchar(max), @block1 varchar(max) declare @output varchar(max) SET @output = '' declare @i int SET @i = 1 while @i <= @l begin set @block1 = @salt +cast(cast(@i as varbinary(4)) as varchar(4)) set @u = dbo.fn_HMAC(@hash_algorithm,@password,@block1) set @t = @u declare @j int SET @j = 1 while @j < @rounds begin set @u = dbo.fn_HMAC(@hash_algorithm,@password,@u) declare @k int SET @k = 0 DECLARE @workstring varchar(max) SET @workstring = '' while @k < @hLen begin set @workstring = @workstring + char(ascii(substring(@u,@k+1,1))^ascii(substring(@t,@k+1,1))) set @k = @k + 1 end set @t = @workstring set @j = @j + 1 end select @output = @output + case when @i = @l then left(@t,@r) else @t end set @i = @i + 1 end return master.dbo.fn_varbintohexstr(convert(varbinary(max), @output )) end GO然後創建儲存過程以生成雜湊密碼
CREATE PROCEDURE [dbo].[EncryptPassword2] @passwordIn AS VARCHAR(MAX), @passwordOut VARCHAR(max) OUTPUT AS -- Generate 16 byte salt DECLARE @saltVarBin VARBINARY(max) SET @saltVarBin = (SELECT CAST(newid() AS binary(16))) -- Base64 encode the salt DECLARE @saltOut VARCHAR(max) SET @saltOut = cast('' as xml).value('xs:base64Binary(sql:variable("@saltVarBin"))', 'varchar(max)') -- Decode salt to pass to function fn_PBKDF2 DECLARE @decodedsalt varchar(max) SET @decodedsalt = convert(varchar(max),(SELECT CAST('' as xml).value('xs:base64Binary(sql:variable("@saltOut"))', 'varbinary(max)'))) -- Build the password binary string from 00 + salt binary string + password binary string created by 32 byte 1000 iteration ORC_PBKDF2 hashing DECLARE @passwordVarBinStr VARCHAR(max) -- Identity V1.0 and V2.0 Format: { 0x00, salt, subkey } SET @passwordVarBinStr = '0x00' + REPLACE(master.dbo.fn_varbintohexstr(@saltVarBin) + (SELECT dbo.fn_PBKDF2('sha1', @passwordIn, @decodedsalt, 1000, 32)),'0x','') -- Identity V3.0 Format: { 0x01, prf (UInt32), iter count (UInt32), salt length (UInt32), salt, subkey } (comment out above line and uncomment below line) --SET @passwordVarBinStr = '0x01000000010000271000000010' + REPLACE(master.dbo.fn_varbintohexstr(@saltVarBin) + (SELECT dbo.fn_PBKDF2('SHA2_256', @passwordIn, @decodedsalt,10000, 32)),'0x','') -- Convert the password binary string to base 64 DECLARE @passwordVarBin VARBINARY(max) SET @passwordVarBin = (select cast('' as xml).value('xs:hexBinary( substring(sql:variable("@passwordVarBinStr"), sql:column("t.pos")) )', 'varbinary(max)') from (select case substring(@passwordVarBinStr, 1, 2) when '0x' then 3 else 0 end) as t(pos)) SET @passwordOut = cast(''as xml).value('xs:base64Binary(sql:variable("@passwordVarBin"))', 'varchar(max)') RETURN最後使用執行儲存過程
DECLARE @NewPassword varchar(100) DECLARE @EncryptPassword VARCHAR(max) select @NewPassword = 'password12344' EXECUTE EncryptPassword2 @NewPassword, @PasswordOut = @EncryptPassword OUTPUT; PRINT @EncryptPassword請注意,儲存過程可能需要針對更高版本的 SQL Server 進行更改,因為這是專門為 2005 年編寫的,我相信在更高版本中轉換為 base64 是不同的。