Sql server SQL Server-密码字段编码 第一个问题:

Sql server SQL Server-密码字段编码 第一个问题:,sql-server,encryption,encoding,passwords,sha1,Sql Server,Encryption,Encoding,Passwords,Sha1,哪一个更好的密码编码 沙一 HashBytes('SHA1','MySecret短语') 加密 EncryptBypass短语('secretKey','123456789') 有没有更好的方法更安全 另一个问题是: 我们可以对密码进行一次以上的编码吗?例如两次编码 都不是。不含盐的散列容易受到彩虹表的攻击。另一方面,密码短语必须以明文形式提交,这使得它容易受到SQL跟踪的攻击 我最近为我当前的项目研究了这个特殊的问题,并最终决定使用salted X.509签名。在数据库中创建证书,并使用其私钥

哪一个更好的密码编码

  • 沙一
  • HashBytes('SHA1','MySecret短语')

  • 加密
  • EncryptBypass短语('secretKey','123456789')

    有没有更好的方法更安全

    另一个问题是: 我们可以对密码进行一次以上的编码吗?例如两次编码

  • 都不是。不含盐的散列容易受到彩虹表的攻击。另一方面,密码短语必须以明文形式提交,这使得它容易受到SQL跟踪的攻击

  • 我最近为我当前的项目研究了这个特殊的问题,并最终决定使用salted X.509签名。在数据库中创建证书,并使用其私钥创建密码签名(+个性化GUID)。即使salt存储为纯文本,也无法将生成的哈希还原回原始密码

  • 基本上,代码如下所示:

    create function [dbo].[security_GetPasswordHash]
    (
        @Password sysname,
        @Salt uniqueidentifier
    )
    
    returns binary(128) with schemabinding, returns null on null input as begin
    
    declare @CertId int, @CertPwd sysname;
    
    set @CertId = ...; -- Get your cert however you like it
    set @CertPwd = ...; -- If your cert is encrypted with password, get it too
    
    return SignByCert(
        @CertId,
        SignByCert(@CertId, @Password, @CertPwd) + cast(@Salt as binary(16)),
        @CertPwd
    );
    end;
    go
    
    这样,即使知道私钥的密码也无法帮助攻击者反转散列。在身份验证存储过程中,您可以使用如下代码来确定密码是否正确:

    -- Try to validate the user
    select @UserId = u.Id
    from dbo.Users u
    where u.LoginName = @Login
        and u.PasswordHash = dbo.security_GetPasswordHash(@Password, u.PasswordSalt);
    
    -- Special case of user existence - there may be a wrong password here, too.
    if @UserId is null begin
        -- The specified user either does not exist, or wrong password has been supplied.
        set @Error = 51008;
        set @Message = dbo.sys_FormatErrorMessage(@Error, @CultureId, default, default, default, default);
        throw 50000, @Message, 1;
    end;
    
    尽管在使用证书时有很多关于昂贵计算的警告,但即使是在一台2岁的笔记本电脑上,这种算法的运行速度也足够快