几年前,我设计了一个对称密钥系统,其工作方式如下:

我实际上不是专家,所以我想知道为什么这样的方法不是很常见。

#1 楼

使用正确的系统(实际上使用密钥),我看到了这些弱点:


如果攻击者可以猜出plaintext_n,他可以从pad_n以及随后的所有ciphertext_n中得出pad_i -意味着他可以阅读其余消息。
密文以H(plaintext)开头,这意味着可以猜测明文的攻击者可以验证此猜测。为避免这种情况,应至少随机填充明文。 (但是您可以简单地将这些随机字节用作初始化向量,而不是使用纯文本的哈希值)。
即使密钥本身具有更大的熵如果您再次向用于创建高阶pad的哈希函数输入密钥,则可能会更好。通过明文,这意味着加密算法不是在线算法(解密是)。

除此之外,您的算法类似于分组密码的输出反馈操作模式,带有从消息派生的初始化向量,并且没有用于以下步骤的新密钥输入。 />
initvec = random
pad_0 = H(key + initvec)
pad_n = H(key + pad_(n-1))

ciphertext = initvec + cipherpart_0 + ... + cipherpart_max


(其余内容与您的示例相同。)

这不执行完整性保护...为此,您应在末尾附加一些密钥MAC(因此它可以是一种在线算法)。

然后,我们实际上具有从哈希函数派生的奇怪的“仅加密”分组密码的OFB模式。唯一的问题是,就像Jack提到的那样,它比普通的分组密码要慢得多。

免责声明:

请注意,尽管这种构造在随机Oracle模型中是安全的(请参阅此博客条目,以获取类似构造的证明,使用计数器而不是先前的哈希值),但该证明使用的是抗冲突性和原像不暗示的属性哈希函数的-resistance属性(这是构造哈希函数的目的)。

评论


$ \ begingroup $
某些散列函数是一个真实的假设,还是应该是加密散列函数?
$ \ endgroup $
–忍者虫
18-10-29在21:53

$ \ begingroup $
@NinjaBug对不起,我不明白您的问题。如果您将此构造与非加密哈希函数(如Java的string.hashCode())一起使用,则我不希望拥有任何类型的安全属性。
$ \ endgroup $
–PaŭloEbermann
18-10-30在12:56

$ \ begingroup $
谢谢,这就是我要的。另一个问题:我是硕士。学生从事计算机网络工作,而我没有密码学背景。对于一个项目,我需要(在其他环境中)装备某种环境中的密码系统。该解决方案不必是最先进的安全解决方案,我只需要能够提出一个连贯的想法即可。由于某些技术原因,我想应用您在此处提出的建议。这有名字吗?如何研究此算法的密码属性并了解更多信息?
$ \ endgroup $
–忍者虫
18-10-30在14:47

#2 楼

实际上,这种方法是相当普遍的。许多流密码都基于此原理进行操作。例如,Salsa20使用有效的哈希函数(PRF)将秘密输入(包括计数器)转换为与纯文本进行XOR的密钥流。但是,这种功能比安全的密码散列要快得多,因为它不需要像密码散列那样防止原像或冲突。例如,OpenSSL的SHA-1在小型输入(在我的台式机上)上的运行速度约为50 MiB / s,而其AES-128的实现则在90 MiB / s的条件下运行。
但是,您的特定方案使您感到困惑。您将第一个填充设置为纯文本的哈希,而不是密钥。因此,给定第一部分密文(H(plaintext)),可以重新分配整个流。如果这确实是您要写的内容,它的运行速度也很慢,因为它要求您先阅读整个消息,然后才能处理其中的任何一条消息。 >我应该提到的是,如果您的消息中包含完整的已知或可猜测的明文块,则您的方案很容易被破坏,因为给定$ pad _ {(i)} $,任何人都可以计算$ pad _ {(i + 1)} $。因此,猜测一个明文块,将其与密文进行$ XOR $运算,以恢复可能的填充值,然后计算下一个填充值,然后查看该块中恢复的密文是否有效。

评论


$ \ begingroup $
另外,我将H(plaintext)放在开头,以便可以全部传输,并可以确认解密的消息。
$ \ endgroup $
–John Gietzen
2011年7月13日在16:50



$ \ begingroup $
您关于速度的陈述是完全错误的,Salsa20被明确地设计为cr.yp.to/snuffle/design.pdf是快速的,并使用add-rotate-xor哈希,因为它们是快速且自然不变当时,AES硬件加速是在2008年推出的,SHA加速是在2013年推出的,因此,当然,AES在2011年在您的计算机上更快,而具有硬件加速的SHA1则更像是500MB / s,另一方面,软件Blake2b甚至比硬件加速的SHA1,与SHA3一样强大,并且也使用add-rotate-xor设计(有趣的是...)
$ \ endgroup $
–丹尼尔·希尔(Daniel Hill)
19年8月30日在23:44

$ \ begingroup $
“但是,[在Salsa20中使用的]这种功能可能比安全的密码散列要快得多”。
$ \ endgroup $
–杰克·劳埃德(Jack Lloyd)
19年8月31日在12:32

#3 楼

您可能对BEAR和LION感兴趣。

http://www.cl.cam.ac.uk/~rja14/Papers/bear-lion.pdf


作者基本上是通过键控哈希函数(函数族$ H_K:{0,1} ^ * \ to {0,1} ^ k $)或普通散列(函数$ H':{0,1} ^ * \ to {0,1} ^ k $)和流密码(函数$ S:\ {0,1 \} ^ k \ to \ { 0,1 \} ^ n $,对于上下文中的任意$ n $;这里$ n = mk $)。大小为$ k $的一个(L)和大小为$ mk $的一个(R),进行加密/解密,并将这两个部分重新组合在一起。我们还有两个密钥$ K_1 $和$ K_2 $,每个密钥的长度为$ k $。

对于BEAR,加密由

$$ L:= L ⊕H_ {K_1}(R)$$
$$ R:= R⊕S(L)$$
$$ L:= L⊕H_ {K_2}(R)$$

和解密的另一种方式:

$$ L:= L⊕H_ {K_2}(R)$$
$$ R:= R⊕S(L )$$
$$ L:= L⊕H_ {K_1}(R)$$

对于LION,我们使用未加密的哈希函数$ H'$,流密码的两次调用而不是哈希函数,而不是两次键控哈希调用。加密: := R⊕S(L⊕K_2)$$

解密:

$$ R:= R⊕S(L⊕K_2)$$
$ $ L:= L⊕H'(R)$$
$$ R:= R⊕S(L⊕K_1)$$

例如在两种情况下,解密都只是用交换的密钥半部分进行加密。

本文证明,只要哪一个组件函数是安全的(例如,破坏组成的原语允许破坏两个组件)。为了增强抵抗其他攻击的能力,还有一个版本(LIONESS),它同时使用密钥哈希和流密码两次。


我真的不明白为什么如果有人已经有了流密码,为什么有人会想要分组密码,但是你去了。另请参阅Jack Lloyd所说的有关Salsa20的内容。 lafs.org/pipermail/tahoe-dev/2010-June/004487.html

评论


$ \ begingroup $
看来,本文使用的流密码术语比使用一种操作模式从分组密码中获得的流密码的类型要窄一些-它只是产生(任意长)密钥的函数来自密钥的流,与密文和明文无关。 (这对应于分组密码的OFB和CTR模式。)
$ \ endgroup $
–PaŭloEbermann
2011年7月17日在12:18

$ \ begingroup $
这就是Wikipedia所谓的同步流密码。
$ \ endgroup $
–PaŭloEbermann
2011年7月17日在12:25

$ \ begingroup $
...,当然还有未注明日期的论文:-((从提交日期起,是2006年7月或更早的日期。)
$ \ endgroup $
–PaŭloEbermann
2011年7月17日在12:31



$ \ begingroup $
我添加了本文所示算法的草图。
$ \ endgroup $
–PaŭloEbermann
2011年7月17日在20:01

#4 楼

答案有两个方面:首先,从安全性方面考虑:如果使用的加密哈希函数无法区分并且使用了适当的填充,则可以在使用时使用结果“哈希流”将使用任何其他流密码(例如RC4)。总而言之,如果函数没有弱点,您还可以轻松地在$ n $块处将密钥流计算为$ H(\ text {key} | n)$,我认为没有理由不安全。第二,真正的可行性。实际上,对密码的共同要求是尽可能快,并且尽管对散列函数也有相似的要求,但通常不会太过强调。即使与基于Feistel网络或类似AES的复杂块密码相比,对于相同块(输出)大小的哈希函数的计算通常也要花很多倍的时间。如果您不介意某些慢速(或仅处理小数据),那可能还可以,但是由于我们有一些安全级别相近的快速流密码,因此这种方法可能不会引起广泛的关注。

简而言之:安全,但相当慢。

PS。,对于您的协议:密文中有$ s = H(\ text {plaintext})$未经加密的攻击者可以简单地找到$ s $的(某些匹配的)原像,并且许多散列函数都存在不错的原像攻击。正如前面的答案所建议的那样,您一定要避免这种情况。