我来自Web开发背景(我对密码学或算法本身的工作原理不甚了解),所以我想用一个简单的词问这个问题。如果使用SHA1进行“测试”:

a94a8fe5ccb19ba61c4c0873d391e987982fbbd3


如果我改用SHA512,然后仅使用输出的前40个字符:

ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff

ee26b0dd4af7e749aa1a8ee3c10ae9923f618980


问题


像这样散列和存储敏感数据是否对安全性有影响? SHA1哈希吗?
使用截短版本时,哈希冲突的风险增加了吗?

有人对此进行辩论引发了争论,他们的理由是这样做会更好之所以使用SHA512版本,是因为它是一种更安全的算法,并且通过将其截断,潜在的黑客根本就不会知道使用哪种算法。

我的理解是SHA1总是会产生唯一的估价e,而SHA512输出的前40个字符可能会出现多次。

评论

您能指出是否可以将标题更改为160位吗?哈希输出通常以位给出...不要忘了按一下接受,我认为它不能比Reid已经解释得更好。

@ e-sushi我正在一个存在C ++函数的环境中工作,该函数称为b2a,它代表“二进制到ASCII”,它将字节数组转换为十六进制表示形式。正确命名事物非常重要。

请注意,使用截断的哈希的临时标准是将最左边的字节用作哈希值(从右边删除字节)。请使用默认值。关于安全性,使用哪个位无关紧要,但是在兼容性方面可能有所不同。

#1 楼

通常,您不应使用SHA1。而是使用SHA-2家族中的一种哈希函数。

就可以截断哈希了,这很好。它已由NIST明确认可,并且SHA-2家族中有哈希函数,这些哈希函数是其全部兄弟的简单截断变体:SHA-256 / 224,SHA-512 / 224,SHA-512 / 256和SHA-512 / 384,其中SHA- $ x $ / $ y $表示全长SHA- $ x $被截断为$ y $位。 (正如Henno Brandsma指出的,从技术上讲,截断版本的起始算法常量是不同的,但这与我要提出的观点有些正交。)


是否存在这样散列和存储敏感数据有任何安全隐患吗?


就从摘要本身确定敏感材料而言,您是安全的。所有安全的现代加密哈希都有所谓的原像抵抗,这实际上意味着,如果可以的话,“反向”哈希是计算上不可行的。因此,您的敏感数据的机密性不会因存储摘要而受到损害。 (注意:有关此内容,请参见下面的Gordon Davisson的评论;在某些情况下可能涉及安全性。)

现在,真正的问题是:为什么首先要存储哈希?希望您不要用它来检测数据是否被恶意修改;通常是MAC的权限范围,例如HMAC或CBC-MAC。


是否比使用完整的SHA1散列更安全或更安全?


实际上,如果您在乎防撞性,那将更加安全。对SHA1的攻击会在260次时间内发现冲突,而将SHA-512截断为160位需要280次才能发现冲突(请参阅生日攻击)。因此,将SHA-2函数之一截断为160位时,其抗碰撞性要强约220倍。 (此外,发现冲突现在已在SHA1的可能性范围之内。因此,如果您正在阅读此书,并且正在构建新系统,则应该选择SHA-2或SHA-3。) >
使用截短版本时,哈希冲突的风险增加了吗?


SHA1上的风险增加了吗?否。使用完整的SHA-512输出会增加风险吗?是。

截断哈希函数的输出总是会降低其(理论上)的抗碰撞性。在实践中,通常没有太大关系。例如280时间仍然很大。不过,如果您使用SHA-256的全部输出,则相同的生日攻击将花费2128时间,这是完全遥不可及的。知道首先使用哪种算法


始终假定攻击者知道除秘密密钥以外与您的算法/密码系统有关的所有信息。这就是Kerckhoffs原理。为什么它很重要已经被充分了解,所以您应该遵循它。


我的理解是SHA1总是会产生唯一的值,而SHA1的前40个字符有可能SHA512输出可能会出现很多次。


SHA1不会产生唯一值。 SHA1有无限多个可能的输入(它需要任何长度的位串),但是只有160位输出。根据信鸽原理,必须有多个值映射到相同的160位输出。 2017年2月,发生了SHA-1碰撞。但是,尽管有信鸽原理保证了它们的存在,但迄今为止尚未公开任何SHA-256冲突。


我要注意的是,如果您要使用的完整输出,请参见SHA1,SHA-256或SHA-512,您应该注意长度扩展攻击。

评论


$ \ begingroup $
“安全隐患”部分的警告:如果明文值是可猜测的(或从有限的集合中选择),则攻击者将能够猜测并测试可能的明文。例如,如果您对地址数据库的“状态”字段进行哈希处理,则将只有50个不同的哈希值,并且攻击者将不会很费力地找出哪个是哪个。同样,如果您对“名称”字段进行哈希处理,并且攻击者想找出“ John Q. Smith”是否在您的数据库中,则他们可以对此进行哈希处理并寻找匹配项。
$ \ endgroup $
–戈登·戴维森(Gordon Davisson)
13年7月27日在14:49

$ \ begingroup $
@GordonDavisson:非常正确。要确定它是否真的安全,我们必须了解该应用程序。
$ \ endgroup $
–里德
13年7月27日在15:04

$ \ begingroup $
请注意,SHA-224不是SHA-256的简单截断版本:IV不同。 SHA-224的计算类似于SHA-256,然后被截断,但是由于IV不同,SHA-224的中间256位结果与SHA-256计算完全不同(通常)。 SHA-384和SHA-512也是一样。
$ \ endgroup $
– Henno Brandsma
13年8月13日在18:07



$ \ begingroup $
在我做过的一些测试中,与相同长度的哈希函数相比,截断的哈希函数导致的冲突要多得多(尽管未截断的版本不会发生冲突)。我当时不认为我使用过sha512,但是例如,比起使用原始值的CRC32,例如将MD5主动截断为4个字节会导致更多的冲突。
$ \ endgroup $
–Ángel
2014年9月10日19:51

$ \ begingroup $
@Ángel一般来说,这不应该是真的。但是CRC32具有特殊的结构,因此取决于您创建这些输入的方式,它可能比理想的哈希少得多的冲突。例如,如果您对4字节消息进行散列,则CRC32不会发生任何冲突,有些人甚至不认为它是散列。
$ \ endgroup $
– CodesInChaos
2015年9月30日14:47

#2 楼

几乎可以肯定,使用160位(40十六进制数字)截断的sha512比sha1安全得多。

首先,sha1具有明显的已知弱点,而sha512没有已知的弱点。 sha512具有更多内部状态。这意味着,如果有人在截断的sha512中发现了碰撞,但在完整的sha512中却没有发现,他们将无法像sha1碰撞那样“扩展”碰撞。



可以扩展一下扩展碰撞的概念吗??


md5 / sha1 / sha2大致按以下方式操作。预处理输入以将其从字节序列转换为块序列。通常,这种预处理包括将填充追加到末尾。即使输入的长度恰好是块的数量,也将添加填充,以避免填充过程引入冲突。
初始化哈希函数的内部状态。
对于输入序列中的每个块,请执行一些处理它使用旧的内部状态和输入块并生成新的内部状态。
输出结果。

对于这些哈希函数的“完整”版本,结果是内部状态。因此,结果冲突与内部状态冲突相同。对于哈希函数的“截断”版本,结果是内部状态的截断版本,因此最终输出中可能会发生冲突,而内部状态中不会发生冲突。如果我们看一下最近在SHA1上发生的碰撞攻击,利用它们的策略就类似。


构造一个通用前缀。通常,它是某种富文件格式的标头。
执行对碰撞块的搜索。
选择一个通用的后缀,其中包含取决于冲突块内容的条件逻辑。

该策略基于这样的事实,即冲突不仅是最终输出中的冲突,而且是内部状态中的冲突。因此,无论攻击者添加了什么后缀,它们都仍然会发生冲突。

如果攻击者具有一种方法,可以在截断的哈希中找到冲突,但在内部状态(即完整哈希)中找不到冲突,那么他们将不会能够在发现冲突后附加任意的后缀,因此必须将其操作顺序更改为。


构造一个公共前缀。
选择一个公共后缀。
/>执行搜索碰撞块。

对于攻击者来说,此操作顺序有两个缺点。他们可能最终找到了一个碰撞,但是该碰撞却没有用,因为它没有以正确的方式触发条件逻辑。
攻击者必须为每个受害者分别寻找碰撞。


评论


$ \ begingroup $
您可以扩展碰撞的概念吗?
$ \ endgroup $
–Paul Uszak
17年6月24日在12:12