T-SQL:加盐密码

8

我正在寻找使用T-SQL存储过程进行密码加盐的示例。当然,还需要一个匹配的存储过程来验证用户。

CREATE PROCEDURE ChangePassword(@Username nVarChar(50), @Password nVarChar(50))

CREATE PROCEDURE ValidateUser(@Username nVarChar(50), @Password nVarChar(50))

3个回答

16
首先,我要冒昧地说,散列密码存储在数据库中通常是一种不良的安全实践。您将无法防止监视数据库流量的流量嗅探器攻击。唯一的保护方式是确保与数据库的连接已加密,这通常意味着所有其他与数据库的流量都将被加密。虽然可以绕过此问题,但更好的解决方案是由应用程序执行哈希处理。
如Sam Saffron所述,您可以使用Hashbytes函数获取SHA1哈希。如果您需要更好的算法,则需要创建CLR过程。盐值将涉及为每个用户存储一个加密随机值,然后将该值附加到密码并通过Hashbytes运行它:
Create Procedure ValidateUser
    @Username nvarchar(50)
    , @Password nvarchar(50)
As

Declare @PasswordSalt varbinary(256)

Set @PasswordSalt = ( Select PasswordSalt From Users Where Username = @Username )

If @PasswordSalt Is Null
        -- generate a salt? 

Declare @Hash varbinary(max)
Set @Hash = Hashbytes('SHA1', @PasswordSalt + Cast('|' As binary(1)) + Cast(@Password As varbinary(100))

If Exists(  Select 1
            From Users
            Where Username = @Username
                And PasswordHash = @Hash )
    -- user is valid

Else
    -- user is not valid

请记住,盐值应该是密码学上随机生成的,因此我不建议使用 NewId() 函数。相反,我建议使用类似于 .NET 的 RNGCryptoServiceProvider 类来生成盐值。


Thomas,我认为加盐的原因是为了防止彩虹表攻击。那么使其具有密码学安全性的理由是什么? - Sam Saffron
2
@Sam Saffron - 不是加密上的安全,而是加密上的随机性。这种随机性减少了盐值的聚集。 - Thomas
@Thomas...不好意思,我不是故意想让你麻烦的。聚类盐会产生什么影响? - Sam Saffron
1
@Jonathan Allen - 如果您正在对密码进行哈希处理,则Web服务器上没有秘密。哈希算法不被视为机密。关于连接。我甚至不确定您是否可以告诉SQL Server加密某些流量而不是其他流量。据我所知,这是全有或全无的。 - Thomas
1
该死,你说得对。我真的希望能够在每个连接上控制是否使用SSL,但实际上只能全局开启或关闭。http://technet.microsoft.com/en-us/library/ms177485.aspx - Jonathan Allen
显示剩余2条评论

2

您可以使用HASHBYTES对字符串进行SHA1加密,然后使用NEWID()生成一个随机的Guid作为盐值。


2
话虽如此,总的来说我现在更喜欢使用BCrypt,这里有很多关于它的信息:https://dev59.com/S3I_5IYBdhLWcg3wBuRs 和 http://stackoverflow.com/questions/3722780/do-any-security-experts-recommend-bcrypt-for-password-storage - Sam Saffron
虽然我不认为你可以在T-SQL中使用bcrypt(无论如何,你的安全代码也不应该存在于T-SQL中...) - Aaronaught
1
我也相当确定newid不具有密码学强度。MD5和SHA1也没有,但是每件事都有程度... - Aaronaught
@Aaronaught,足以击败彩虹表 :) 使用盐值的SHA1的问题在于可以使用暴力破解攻击。 - Sam Saffron
@Thomas,当然,但对于您在未加密的数据库中存储的任何敏感信息也是如此。就个人而言,我不会将这种代码放在我的数据库服务器上,因为它感觉不太合适。 - Sam Saffron
显示剩余4条评论

1

你有没有考虑在应用程序级别上对密码进行加盐,特别是对于应用服务器的硬件(尤其是 CPU),可能比数据库管理系统更适合处理哈希和加盐?


这主要是出于好奇心。话虽如此,这样可以允许多个应用程序而无需构建某种中间件。 - Jonathan Allen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接