Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Generuj skrót hasła członkostwa ASP.Net w czystym T-SQL

Napisałem hash przechowywane proc przez odwrócenie kodu C# stąd Domyślny hasher haseł ASP.NET Identity, jak to działa i czy jest bezpieczny? i kilka fantastycznych funkcji SQL PBKDF2 stąd Czy istnieje Implementacja SQL PBKDF2?

Najpierw utwórz te dwie funkcje zaczerpnięte z Czy istnieje SQL wdrożenie 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

i

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

następnie utwórz przechowywaną procedurę, aby wygenerować hasło skrótu

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

Na koniec wykonaj zapisany proces za pomocą

DECLARE @NewPassword varchar(100)
DECLARE @EncryptPassword VARCHAR(max)

select @NewPassword = 'password12344'                                           

EXECUTE EncryptPassword2 @NewPassword, @PasswordOut = @EncryptPassword OUTPUT;

PRINT @EncryptPassword

Należy pamiętać, że przechowywany proc może wymagać zmiany w późniejszych wersjach serwera SQL, ponieważ został on napisany specjalnie dla 2005 i wierzę, że konwersja do base64 jest inna w późniejszych wersjach.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Zapytanie SQL dla łańcucha rodzic-dziecko

  2. Poprawka:„Oświadczenie BACKUP LOG jest niedozwolone, gdy model odzyskiwania jest PROSTY” w SQL Server (i SQL Edge)

  3. Jak utworzyć procedurę składowaną w SQL Server

  4. Wybierz kolumny z jednej tabeli na podstawie nazw kolumn z innej tabeli

  5. SQL Server :wybierz ostatni wynik z grupy według