与截断的SHA-256哈希冲突的概率

时间:2013-11-13 19:15:55

标签: math hash probability sha sha256

我有一个数据库驱动的Web应用程序,其中所有数据行的主键被混淆如下:SHA256(内容类型+主键+秘密),截断为前8个字符。内容类型是一个简单的单词,例如“post”或“message”,秘密是20-30 char ASCII常量。结果存储在单独的索引列中,以便快速进行数据库查找。

如何计算此场景中哈希冲突的概率?我根本不是数学家,但是一位朋友声称,由于生日悖论,对于10,000行的8-char截断,碰撞概率约为1%。这个说法有什么道理吗?

1 个答案:

答案 0 :(得分:3)

是的,存在碰撞概率&它可能有点太高了。确切的概率取决于“8个字符”的含义。

“8个字符”是否意味着:

  • A)您存储哈希的8个十六进制字符?这将存储32位。
  • B)您存储了8个BASE-64字符?这将存储48位。
  • C)您存储了8个字节,以某些单字节字符集编码/或以某种破碎的方式入侵到字符编码中?这将存储56-64位,但如果你没有正确编码,你将遇到字符转换问题。
  • D)你存储8个字节,作为字节?这真的存储了64位的哈希值。

将二进制数据存储为A)十六进制或D)二进制字节,将是我的首选选项。但我肯定建议重新考虑你的“密钥混淆”方案,或者显着扩展存储的密钥大小以减少(当前过度的)密钥冲突的概率。

来自维基百科:http://en.wikipedia.org/wiki/Birthday_problem#Cast_as_a_collision_problem

这种更一般意义上的生日问题适用于散列函数:在发生碰撞之前可以生成的预期N位散列数不是2 ^ N,而是仅2 ^(N / 2)。 / p>

由于在最保守的上述对你的设计的理解中(将其读作A,8个十六进制的字符= = 32位),如果它的存储量大约为64,000行,那么你的方案将会发生碰撞。我认为这种结果对所有严肃甚至玩具系统都是不可接受的。

交易表可能有数量,允许业务增长,每天1000到100,000个交易(或更多)。系统应设计为100年(36500天),内置10倍增长因子,所以..

让你的键控机制真正健壮,并且专业上有用的,你需要能够扩展它以潜在地处理~360亿(2 ^ 35)行而不会发生冲突。这意味着70多位哈希值。

例如,源控制系统Git存储160位SHA-1散列(40个十六进制= 20字节或160位)。用<预计不会发生碰撞。存储的文件修订版少于2 ^ 80个。


可能更好的设计可能是,而不是散列&完全伪随机化密钥&希望(反对希望)避免冲突,将8-10位哈希添加/附加/折叠到密钥中。

这将生成一个更大的密钥,包含原始密钥的所有唯一性以及8-10位验证。然后将验证尝试访问密钥,并且将超过3个无效请求视为通过“探测”密钥空间&会触发半永久性锁定。

这里唯一的主要成本是适度缩小给定int-size的可用键空间大小。进出浏览器的32位int将有8-10位专用于安全性,因此实际密钥为22-24。所以你使用64位整数是不够的。