【问题标题】:SQL Server - Password Field EncodingSQL Server - 密码字段编码
【发布时间】:2014-10-25 20:38:12
【问题描述】:

第一个问题:

哪个更好地编码密码?

  1. SHA1

HashBytes('SHA1','MySecret Phrase')

  1. 加密

EncryptByPassPhrase('secretKey', '123456789')

有没有更好的方法更安全?

还有一个问题是:

我们可以对密码进行 1 次以上的编码吗?例如两次编码?

【问题讨论】:

    标签: sql-server encryption encoding passwords sha1


    【解决方案1】:
    1. 两者都不是。没有盐的哈希很容易受到彩虹表的攻击。另一方面,密码必须以明文形式提交,这使得它容易受到 SQL 跟踪。

    2. 我最近为我当前的项目研究了这个特殊问题,并最终决定使用加盐的 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 年的笔记本电脑上,该算法也足够快。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-08
      • 2016-02-04
      • 1970-01-01
      • 2018-01-15
      • 2010-09-15
      相关资源
      最近更新 更多