GUID是否是一个好的盐?我的注册/登录流程有什么漏洞吗?

18

如果我的数据库中的表格如下所示:

 userid uniqueidentifier
 username varchar(20)
 password varbinary(max)

当用户提交注册时,我将用户名和密码发送给存储过程。

存储过程使用NEWID()创建一个新GUID,然后使用SQL Server的HashBytes(sha1)函数基于提供的GUID和密码创建密码,最后将值插入上面的表中。

当用户提交登录时,我将用户名和密码发送给存储过程。

存储过程查找用户名并获取userid,以比较guid+密码的HashBytes(sha1)与密码字段。

您是否看到任何逻辑上的缺陷?

5个回答

15

这很标准 - 对于盐来说,使用guid是可以的。盐的作用是防止彩虹攻击,任何随机的值(即使不随机,则至少要不同)对于每个用户都可以起到作用。


2
我想您是指盐的作用。此外,它必须对于每个用户看起来都是随机但唯一且静态的(否则如何进行检查?) - Bob Gettys
3
盐值的作用是为了防止彩虹表攻击。为此,该值甚至不需要是随机的,只需对于每个用户来说是不同的即可。 - Michael Borgwardt

5
如果安全是主要考虑因素,我宁愿不使用GUID作为盐值。
GUID有不同的“类型”,其中一些比其他类型更“随机”。然而,即使是最好的GUID类型(从“随机性”角度来看,这将是V4类型的GUID),也不适合密码学函数。
GUID的维基百科文章中可以了解到:

V4 GUID使用后期算法,这是一个伪随机数。这些具有相同位置上的“4”,例如{38a52be4-9352-453e-af97-5c3b448652f0}。更具体地说,在第一种情况下,“data3”位模式将为0001xxxxxxxxxxxx,而在第二种情况下,则为0100xxxxxxxxxxxx。对WinAPI GUID生成器的密码分析显示,由于V4 GUID序列是伪随机的,因此在给定初始状态的情况下,可以预测由函数UuidCreate返回的下一个250,000个GUID。这就是为什么GUID不应用于密码学,例如作为随机密钥。


1
很有趣的是,但既然GUID用于盐值,它真的会不安全吗? - Fredou
11
生成盐的机制不需要是随机或不可预测的,即可实现盐的作用。 - Rex M
1
任何可预测的盐值都会削弱整体安全性。理想情况下,每个盐值都应该是唯一随机的,并且与所有其他盐值在完整的盐值数据集中没有相关性或可预测性。 - CraigTP
1
如果每个密码都使用相同的盐值,那么攻击者在一组完整的密码中发现一个密码的盐,就可以轻松计算出整个哈希密码集的“彩虹表”。 @Rex M - CraigTP
2
@CraigTP 没有人说过要使用相同的盐。 - Rex M
3
GUID的彩虹表有多大? - Tyler

1

如描述所述,机制的工作方式不清楚 - 我假设userid字段包含生成的GUID(否则我不知道如何检索它进行比较)。

有不同类型的GUID,并非所有GUID都是随机的。但是,对于密码加盐,实际上并不需要随机性。总的来说,您的方法看起来很好,尽管您可以考虑多次执行哈希({{link2:“密钥强化”}})以进一步提高安全性。


是的,它将是生成的 GUID,我将使用来自 SQL Server 2005 的 NEWID()。 - Fredou

-1
正如Craig Stuntz所指出的那样,您不应该尝试自己进行加密。salt的定义在这里。正如它所说,这应该是随机的,而您的GUID可能不是随机的,因此可能会有信息泄漏和降低的安全性。话虽如此,这取决于您希望为系统提供多少安全性。如果这不是一个大型应用程序,那么您可能可以通过当前系统来实现。

它将使用 SQL Server 2005 中的 newid() 函数。 - Fredou
盐值的随机性并不是为了安全,而是为了避免检查冲突而导致性能下降。盐值需要独一无二即可。伪随机就可以,只要它非常非常有可能是唯一的。话虽如此,在任何可能的情况下,尽可能使用加密强度的随机数生成器。 - Bengie

-2

为什么你在不理解nonce的情况下要重新发明登录功能?

  1. 涉及到加密的任何操作都很难。 专家会犯错,这些错误会被其他专家忽略数十年。我们其他人更差。
  2. 有很多免费的现成认证系统可供使用。几乎所有这些系统都比你自己编写的更好实现和更灵活。

根据评论中的新细节更新。对于使用SQL Server与Windows GUI应用程序交互的认证选择我会从以下入手:

  1. 域身份验证(简单,但需要域名)。
  2. Cardspace。不难,非常灵活,但需要客户端基础设施。
  3. SQL Server混合模式身份验证(简单,但不灵活)。
  4. Kerberos通过SSPI(更难,但非常可配置)。

17
你能指出这篇文章中的实际缺陷吗?我的意思是,他并没有自己编写哈希函数之类的东西,而是在密码哈希值上加盐。这是一件相当普遍的事情,而且与“不要自己编写安全函数”的建议相去甚远。 - Tomalak
7
我不确定我是否理解你的观点(至少对于这个问题是这样)。给密码哈希加盐与加密无关。应用程序的其他部分并未参与讨论,问题也不是“如何实现坚不可摧的登录过程”。 - Tomalak
如果你认为“对密码哈希进行加盐不属于加密相关”,那么你就不应该在这个主题上提供建议。 - Craig Stuntz
1
@Craig Stuntz:当然它是相关的,就像“属于同一类别”。但正如我所说,从给密码哈希/加盐到实际上编写自己的加密/哈希函数是一个长远的过程。前者是使用现有基础设施来完成常见任务。这是可以接受的。后者应该留给专家来处理。 - Tomalak
域身份验证不是一个选择吗?那将是我的首选。我的第二选择将是SQL Server混合模式身份验证(简单,但不灵活)。第三个选择是通过SSPI的Kerberos(更难,但非常可配置)。我会将此添加到答案中。 - Craig Stuntz
显示剩余8条评论

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