我的 SHA1 字符串是不是有可能是非唯一的? [复制]

Posted

技术标签:

【中文标题】我的 SHA1 字符串是不是有可能是非唯一的? [复制]【英文标题】:Is there any chance of my SHA1'd string being non-unique? [duplicate]我的 SHA1 字符串是否有可能是非唯一的? [复制] 【发布时间】:2013-03-13 20:27:21 【问题描述】:

我有以下 sn-p 我正在构造一个字符串以作为电子邮件确认码发送给用户:

$confirmation_code = $user_id . time() . date('d-m-Y',time());
$confirmation_code = sha1($confirmation_code);

$confirmation_code 是否有可能在任何步骤中被复制?

注意:请记住,$user_id 对于每个用户都是唯一的

【问题讨论】:

看看这个相关的帖子:security.stackexchange.com/questions/29071/… 也请考虑this note 【参考方案1】:

鉴于$user_id 对每个用户都是唯一的,这应该(理论上)意味着您的确认代码永远不会发生冲突(“不唯一”)

然而,实际上,SHA1 哈希可能发生冲突(请参阅this MSDN blog article 了解更多信息)。

因此,如果您问这个问题的原因是您可以决定是否在数据库中创建列 UNIQUE,请不要。

【讨论】:

文章中的重大错误 - MD5 散列的长度为 16 个字节。十六进制编码时它们只有 32 个字节长。 @Alnitakt 似乎作者将 32 个字符的字符串长度与字节数混淆了。 是的,我就是这么说的。【参考方案2】:

是的,代码应该是唯一的,除非您每秒为每位用户生成多个代码。它也非常可预测。如果攻击者知道用户的 id 以及生成代码的粗略时间,那么猜测代码就很容易了。如果允许攻击者无限次猜测,那么即使是粗略的时间也无关紧要,因为他可以轻松尝试过去几年的所有有效代码。

您应该真正生成一个(伪)随机代码,而不是基于相当静态数据的代码。在 Linux 上,只需阅读 /dev/random:

$code = bin2hex(file_get_contents('/dev/random', false, null, -1, 32));
                                                                  ^^
                                                          desired length/2

【讨论】:

以上是关于我的 SHA1 字符串是不是有可能是非唯一的? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

PHP生成唯一ID的方法

如何在元素列表中找到最大的数字,可能是非唯一的?

开放平台appkey,appSecret设计与生成

使用哈希作为唯一 ID 是错误的吗?

CRC32+大小与 MD5/SHA1

python 中md5 和 sha1 加密, md5 + os.urandom 生成全局唯一ID