Generate ASP.Net Membership password hash in pure T-SQL

后端 未结 5 1760
天命终不由人
天命终不由人 2020-12-31 10:32

I\'m attempting to create a pure t-sql representation of the default SHA-1 password hashing in the ASP.Net Membership system. Ideally, what I would get would be this:

<
5条回答
  •  被撕碎了的回忆
    2020-12-31 10:54

    if you are running 2005 or higher, you can create a CLR (.NET) UDF:

    [SqlFunction(
      IsDeterministic = true, IsPrecise = true, 
      DataAccess = DataAccessKind.None,
      SystemDataAccess = SystemDataAccessKind.None
    )]
    public static string EncodePassword(string pass, string salt) {
      byte[] bytes = Encoding.Unicode.GetBytes(pass);
      byte[] src = Convert.FromBase64String(salt);
      byte[] dst = new byte[src.Length + bytes.Length];
      Buffer.BlockCopy(src, 0, dst, 0, src.Length);
      Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length);
      using (SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider()) {
        return Convert.ToBase64String(sha1.ComputeHash(dst));
      }
    }
    

    you need to include the following namespaces in your class:

    using Microsoft.SqlServer.Server;
    using System.Data.SqlTypes;
    

    the class must be public.

    build the .dll then run the following (per database you want to call the UDF) SQL statement:

    sp_configure 'clr enabled', 1
    GO
    RECONFIGURE
    GO
    
    IF OBJECT_ID (N'dbo.EncodePassword', N'FS') IS NOT NULL
      DROP FUNCTION dbo.EncodePassword;    
    IF EXISTS (SELECT name FROM sys.assemblies WHERE name='UDF')
    DROP ASSEMBLY UDF
    
    CREATE ASSEMBLY UDF FROM 'FULL_PATH_TO.dll' WITH PERMISSION_SET=SAFE    
    GO
    
    CREATE FUNCTION EncodePassword(
      @pass NVARCHAR(4000),
      @salt NVARCHAR(4000)
    )
    RETURNS NVARCHAR(4000)
    -- return NULL if any input parameter(s) are NULL
    WITH RETURNS NULL ON NULL INPUT
    AS
    EXTERNAL NAME UDF.[NAMESPACE.CLASSNAME].EncodePassword
    GO
    

    obviously, replace 'NAMESPACE.CLASSNAME' with the namespace (if any) and name of your class. and you might want to mess with the input parameter and return value sizes.

    then call the UDF with T-SQL:

    SELECT UserName,Password
    ,dbo.EncodePassword('PASSWORD', PasswordSalt) As TestPassword 
    FROM aspnet_Users U 
    JOIN aspnet_membership M ON U.UserID = M.UserID
    

    works for me :)

提交回复
热议问题