sql >> データベース >  >> RDS >> Sqlserver

純粋な T-SQL で ASP.Net メンバーシップ パスワード ハッシュを生成する

    ここ ASP.NET Identity の既定のパスワード ハッシャー、どのように機能し、安全ですか? ここからいくつかの素晴らしい PBKDF2 SQL 関数 PBKDF2 の SQL 実装?

    最初に Is there a SQL から取得したこれら 2 つの関数を作成します。 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 [email protected] -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
    

    これは2005年用に特別に作成されたものであり、以降のバージョンではbase64への変換が異なると信じているため、SQLサーバーの以降のバージョンではストアド プロシージャを変更する必要がある場合があることに注意してください。



    1. Laravelの移行内からmysqlDBエンコーディング文字セットを変更することは可能ですか?

    2. VB.NETmySQL挿入コマンド

    3. MySQLなぜcursor.execute(sql、multi =True)は機能しないが、2 cursor.execute(sql)は機能するのですか?

    4. 多対多の関係の例