我正在开发一个系统(以太坊),在该系统中存储32字节比33字节便宜得多。我想创建一个基于其哈希值存储数据的表。

Sha256将满足此条件,因为它输出32个字节。

但是,我还要希望在将来需要更改哈希算法的情况下添加“版本”字节。这将需要33个字节。

一个简单的解决方案是简单地切掉最后一个字节,只使用前31个字节进行查找。


这样做吗
以任何方式使哈希值有偏差吗?
我的假设是,这会使反向哈希值所需的计算能力降低1/256。
我的假设是,这将使哈希冲突的可能性增加25600%。那是正确的吗?


#1 楼



这是否以任何方式使散列产生偏差?



我们希望在输出位上使用雪崩准则,即对any进行更改输入位的整数必须随机影响输出位的一半。哈希函数的每一位都必须取决于输入位。删除一点不会影响其他。



我的假设是,这将使反向散列所需的计算能力降低1/256。是吗?




首先,哈希函数并不是真正可逆的,因为它们是压缩函数,也就是说,它们从较大的输入空间映射到较短的空间。

$$ H:\ {0,1 \} ^ * \ rightarrow \ {0,1 \} ^ l $$

如果我们想谈谈碰撞阻力,请参阅下一个答案。
对于一般的图像前搜索,可以;如您所述,它将降低计算能力。



我的假设是,这将使哈希冲突的可能性增加25600%。正确吗?




碰撞抵抗力是通过一般的生日攻击来衡量的,即$ \ sqrt {2 ^ l} $,$ l $是输出大小哈希函数。 SHA256具有$ \ sqrt {2 ^ {256}} = 2 ^ {128} $通用生日攻击时间。

对于您而言,我们将以$ \ sqrt {2 ^ {256-8}} = 2 ^ {124} $作为通用生日攻击时间。因此,我们在攻击时间内加快了$ 2 ^ {4} = 16 $的速度。

TL; DR:将哈希值截断为31个字节将是安全的(另请参见此堆栈交换答案


注1:比特币矿工达到$ \约2 ^ {92} $ 2019年8月6日每年SHA-256哈希值。.

注2:FIPS180-4中定义的SHA-224是通过使用不同的首字母截断SHA-256哈希值来计算的用于域分离的常量,因此该值与SHA-256值的前28个字节不同。

评论


$ \ begingroup $
非常感谢!快速的问题是,为什么在计算通用生日攻击时间时减去256除以32?我将输出大小减少1字节(8位)而不是32位。
$ \ endgroup $
– Aakil Fernandes
18年11月25日在22:04

$ \ begingroup $
应该是8,我的错。让我纠正。
$ \ endgroup $
– kelalaka
18-11-25在22:05



$ \ begingroup $
@kelalaka-FWIW,您提出的正是某些SHA变体的工作方式。例如,SHA-224通常通过生成SHA-256并切掉4个字节来实现。因此,您可以简单地说您正在使用SHA-248
$ \ endgroup $
–slebetman
18年11月26日在9:57

$ \ begingroup $
@ slebetman,IIRC,SHA-224也使用不同的初始化常量,因此,它给出的结果与SHA-256截短后的结果不同。不,您不能说“您正在使用SHA-248”,因为在任何标准中都不存在这样的东西。您可以说您正在使用SHA-256截断为248位,因为这就是您正在做的。
$ \ endgroup $
–ilkkachu
18年11月26日在11:19