删除字节时的 SHA 冲突概率

Posted

技术标签:

【中文标题】删除字节时的 SHA 冲突概率【英文标题】:SHA collision probability when removing bytes 【发布时间】:2012-09-17 08:46:53 【问题描述】:

我正在实现一些使用可变长度 id 的程序。这些 id 标识一条消息并发送到将执行某些操作(与问题无关)的代理。但是,代理中此 ID 的最大长度为 24 个字节。我正在考虑使用 SHA 对 id 进行哈希处理(在发送到代理之前)并删除一些字节,直到它只得到 24 个字节。

但是,我想知道这会增加多少碰撞。所以这就是我到目前为止得到的:

我发现对于“完美”哈希,我们有公式 p^2 / 2^n+1 来描述冲突的概率,其中 p 是消息的数量,n 是消息的大小(以位为单位)。这是我的问题开始的地方。我假设从最终哈希中删除一些字节,函数仍然保持“完美”,我仍然可以使用相同的公式。所以假设我得到:

 5160^2 / 2^192 + 1 = 2.12x10^-51

其中 5160 是消息的选择数,192 基本上是 24 字节中的位数。

我的问题:

我的假设正确吗?通过删除一些字节,哈希是否保持“完美”。

如果是这样,并且由于概率非常小,我应该删除哪些字节?最重要还是最不重要?这真的很重要吗?

PS:欢迎任何其他达到相同结果的建议。谢谢。

【问题讨论】:

【参考方案1】:

但是,代理中此 ID 的最大长度为 24 个字节。我正在考虑使用 SHA 对 id 进行哈希处理(在发送到代理之前)并删除一些字节,直到它只得到 24 个字节。

SHA-1 仅输出 20 个字节(160 位),因此您需要对其进行填充。至少如果所有字节都有效,并且您不限于十六进制或 Base64。我建议改用截断的 SHA-2。

我的假设正确吗?通过删除一些字节,哈希是否保持“完美”。

差不多。截断散列应该保留其所有重要属性,显然是在与较小输出大小相对应的降低的安全级别上。

如果是这样并且由于概率非常小,我应该删除哪些字节?最重要还是最不重要?这真的很重要吗?

这根本不重要。 NIST 定义了一种截断的 SHA-2 变体,称为 SHA-224,它使用不同的初始状态获取 SHA-256 的前 28 个字节进行哈希计算。


我的建议是使用 SHA-256,保留前 24 个字节。这需要大约 2^96 次散列函数调用才能找到一个冲突。这目前是不可行的,即使对于极其强大的攻击者也是如此,而且对于意外碰撞来说基本上是不可能的。

【讨论】:

完美男人。非常感谢。实际上我忘了提到我也仅限于字母数字字符,所以我需要对它进行十六进制消化。但无论如何,你的回答几乎告诉了我我需要知道的一切。非常感谢。 如果限制为 24 个十六进制字符,则不能假设 192 位散列函数,而只能假设 96 位散列函数,这太小了。考虑改用 Base64 或至少 Base32。 是的,确实如此。我忽略了将其转储为十六进制会使其在截断为 24 个字符时变得更小。好的,我会重新考虑策略并考虑 Base64。无论如何,感谢您对哈希的帮助。 从哈希中获取第一个(索引最低的,最左边的)字节似乎是行业标准,所以我建议遵循它。

以上是关于删除字节时的 SHA 冲突概率的主要内容,如果未能解决你的问题,请参考以下文章

哈希算法

哈希算法之md5和sha1

散列密码的最佳实践 - SHA256 还是 SHA512?

字节 一面 面经

如何删除错误:捆绑失败:ReferenceError:未计算文件的 SHA-1

Azure DevOps 删除了 sha1 支持