哪一个更适合编码密码?
HashBytes('SHA1','MySecret Phrase')
EncryptByPassPhrase('secretKey', '123456789')
有更好的方法更安全吗?
我们可以对密码进行1次以上的编码吗?例如两次编码?
答案 0 :(得分:1)
都不是。没有盐的哈希很容易受到彩虹桌的攻击。另一方面,密码必须以明文形式提交,这使得它容易受到SQL跟踪的攻击。</ p>
我最近为我当前的项目研究了这个特定问题,最终决定使用盐渍X.509签名。您在数据库中创建证书并使用其私钥创建密码签名(+个性化GUID盐)。即使盐以纯文本形式存储,生成的哈希也无法恢复为原始密码。
基本上,代码如下所示:
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年前的笔记本电脑上,此算法也能够快速运行。