例如,我想产生一个与输入长度相同的哈希值。我想到的一种方法是仅以某种方式加密输入,但这很容易破解,因为可以解密。
我想过的另一种方法是将输入分成128个块,然后在每个部分上进行MD5(或其他哈希处理),然后仅使用所有的弦。但是,我看到一个字节的输入更改仅会更改输出的128位。
#1 楼
作为D.W.请注意,您可以使用任何常规哈希函数的输出来键入流密码(或以流式传输方式(如CTR)使用分组密码),然后将密码的输出作为摘要。但是,现代哈希函数设计中存在一种趋势,可以直接支持任意长度的输出,而无需其他层。例如,加密海绵构造具有内置的此功能:您吸收海绵中的输入,然后根据需要从中挤出尽可能多的输出。
在5个SHA-3决赛入围者中,两个-Skein和Keccak-支持任意输出长度。凯卡克(Keccak)通过做为海绵状哈希来做到这一点。相反,Skein内部使用的系统与DW的CTR模式构造非常相似,重新使用了Threefish可调整的块密码来进行输入压缩和输出生成。
即使在SHA-3竞争仍在进行中最初的时间表要求获胜者已于几个月前宣布。尽管如此,到目前为止所有决赛入围者都幸存下来的事实确实表明,他们很有可能足够用于实际目的。
#2 楼
当然。如果您想要消息$ m $的$ b $位哈希,请使用AES-CTR(SHA256($ m $))的前$ b $位。这样就可以解决问题。换句话说,计算SHA256($ m $)并将所得的256位字符串视为256位AES密钥。接下来,在计数器模式下(使用此键)使用AES生成无休止的伪随机位流。从此流中获取前$ b $位,并将其称为您的哈希。 (请确保不要将IV视为此流的一部分,因为IV不会是伪随机的。您可能需要先手动删除IV才能获取前$ b $位。)
安全性。只要$ b \ ge 160 $左右,这应该是安全的。特别是,鉴于我们目前对AES和SHA256的了解,预计碰撞攻击将花费大约2 ^ {\ min(b,256)/ 2} $的计算步骤。因此,只要您没有选择太小的$ b $值,您就应该很好。选择大于256的$ b $值并不能为您提供更好的抵御冲突的安全性,但这无关紧要:对于任何合理的应用程序,安全性级别已经远远不够,所以您很好。
评论
$ \ begingroup $
这可能是一个愚蠢的问题,但是您可以将零填充缓冲区作为纯文本(大小为b位)传递给AES块密码(例如CBC或其他),使用SHA-256哈希来得出密钥和初始化向量,然后将密文的前b位用作输出?这样安全吗?有关Node.js的实现,请参见gist.github.com/4600432。
$ \ endgroup $
–BMiner
13年1月23日,0:35
$ \ begingroup $
@BMiner,取决于模式。对于CBC模式,只要您确保先删除IV(因为IV不会是随机的),然后取剩余密文的前$ b $位,此方法就起作用。我希望其他类似的模式也可以使用类似的方法,但是我并没有仔细考虑。
$ \ endgroup $
– D.W.
13年1月23日在9:30
$ \ begingroup $
感谢您的回复。您的意思是“确保先删除IV?”在Node.js中,如果将“密码”传递给密码的构造函数,则将使用EVP_BytesToKey派生密钥和IV。这意味着IV不会是随机的,但这不是这个主意吗?如果IV是随机的,您将不会获得一致的,可预测的哈希结果?
$ \ endgroup $
–BMiner
2013年1月24日15:51
$ \ begingroup $
@BMiner,有时某些加密库会为您生成IV,并将IV包含在密文中。换句话说,在加密时,您传递密钥和消息,然后返回一个密文,其中密文在其中的某处包含IV。如果您的库是这样的,则需要删除IV(并确保IV始终从0开始)。如果您自己实现AES-CTR,这将变得更加容易,因此您可以强制将其从IV 0开始,并确保输出仅包括生成的伪随机流(而不包括IV)。
$ \ endgroup $
– D.W.
2013年1月24日19:11
$ \ begingroup $
@curious,这是一个不同的问题,可能最好分开回答,但简洁的答案是:将SHA256(m)的输出视为256位整数,以360为模对其求余,然后使用余数a您的随机数。
$ \ endgroup $
– D.W.
2014年3月18日在17:41
#3 楼
通常,用于输入的(安全)哈希函数与用于输出的(确定性)伪随机数生成器的每种组合在这里都可以工作-D.W.给出的一个“最新技术”示例。 (使用AES-CTR作为PRNG,使用SHA-256作为哈希)。另一种方式类似于PBKDF-2进行正确长度输出的方式:哈希输入(或哈希的哈希)。输入)多次,每次都使用不同的前缀,然后将这些输出连接起来:
output = H(1 || M) || H(2 || M) || H(3 || M) || ...
(可以说这是之前的一般情况的特例,在至少在H已经是原始消息的哈希的情况下。)
有一些具有“任意输出长度”模式的哈希函数,例如Skein(SHA-3候选对象之一)。 (这种Skein模式在内部就像上面的方案一样工作,但是它隐藏在一个标准的原始语言中,您不必自己构建它。)
SHA-3竞赛的真正赢家Keccak的模式也具有任意长度的输出(只要根据需要挤压海绵即可产生所需的输出),其标准化为SHAKE128和SHAKE256(数字表示防撞的安全级别,如果输出的话)长度至少是长度的两倍)。
#4 楼
是的,有类似哈希的算法,无需任何额外的努力就可以产生可变长度的输出。这是“海绵功能”的作用。一种这样的海绵构造就是KeccaK,它是SHA-3竞赛的五支决赛选手之一。评论
$ \ begingroup $
SHA-3的哈希值是多少?或sha3产生多少哈希值?
$ \ endgroup $
–user8238
2013年9月4日在12:28
$ \ begingroup $
SHA3尚未标准化,因此摘要不可用。理论上,通过一次“挤压”,Keccak测试值的范围介于1位和1599位之间
$ \ endgroup $
– Richie车架
2013年9月4日16:46
$ \ begingroup $
两个“任意输出长度”变体被标准化为SHAKE128和SHAKE256。
$ \ endgroup $
–PaŭloEbermann
19年1月18日在17:39
#5 楼
我对你的目的很好奇。通常,涉及消息摘要的主要操作最终是比较两个摘要值。散列密码允许比较摘要值,而不是在系统周围携带超级秘密密码。散列消息使发送方和发送方可以验证是否正确接收了数据,而无需重新发送整个消息。使用私钥加密哈希可以使用公钥对它们进行解密,然后进行比较以验证签名者的身份。即使是数据库中的哈希字符串,也可以通过对摘要值进行比较和排序来进行有效的索引搜索。在每种比较情况下,摘要值具有相等的大小就可以进行比较-不相等的大小将永远不会导致相等的结果。
如果存在大小限制,则在了解保真度相应损失的情况下,总是可以将加密安全摘要值截断。 (非安全的摘要算法可能没有使这种假设变得安全的位散布属性。)
但是您已经说过想要“更大的”摘要。当我想到摘要的含义时,对我来说,这是一个“摘要”,总是小于摘要。您希望通过扩大规模获得什么?是否不信任2 ^ 256种可能性的抗冲突特性?你激起了我的好奇心。
评论
$ \ begingroup $
感谢您的回答。自从您问:我的问题的原因根本不深。我曾考虑过密钥/密码的填充,并且正在思考可以填充密钥特定长度的哈希来代替填充密钥。因此,所有密钥长度都应为“允许”,但我不知道这是否安全。在我进一步考虑之后,我可能会问一个问题。
$ \ endgroup $
–托马斯
2012年8月20日23:21
$ \ begingroup $
我明白你要干什么。现在通常将随机字节而不是固定值用于密钥填充,以避免向攻击者提供婴儿床。这些字节的关键属性是不可预测性,因此不能对您使用。我可以看到为什么散列可以是您考虑使用的东西而不是随机值,但是它仍然必须是随机数的哈希,因此攻击者无法使用它。当您深入了解时,加密随机字节已经是解决此问题的很好的方法。
$ \ endgroup $
–约翰·迪特斯
2012年8月26日5:15
评论
$ \ begingroup $
实际上,SHA-3时间表是“到2012年底”,因此它与人们期望的时间表有关。
$ \ endgroup $
–乔恩·卡拉斯(Jon Callas)
2012年8月21日19:19
$ \ begingroup $
注意,不幸的是,NIST并未考虑任意输出长度,因此该功能是否会像使用特定大小的散列一样受到严格审查尚待观察。而且,如果决赛入围者实际上包含该功能,那么由于没有定义生成随机输出的方法,因此它可能在许多实现中都不存在。
$ \ endgroup $
–马腾·博德威斯♦
2012年8月25日在16:30
$ \ begingroup $
作为对未来读者的说明,在此问题的大部分答案都已写完一年之后,SHA-3竞赛现在已经决定。 Keccak被选中。
$ \ endgroup $
–里德
2013年9月4日13:18
$ \ begingroup $
从那时起,凯卡克(Keccak)的任意输出变量就被标准化为SHAKE128 + SHAKE256。
$ \ endgroup $
–PaŭloEbermann
19年1月18日在17:41