对称密码
从文字密码到比特序列密码
现代的密码都是建立在计算机的基础之上的,这是因为现代的密码所处理的数据量非常大,而且密码算法也非常复杂,不借助计算机的力量就无法完成加密和解密的操作。
计算机的操作对象并不是文字,而是由0和1排列而成的比特序列。无论是文字、图像、声音、视频还是程序,在计算机中都是用0和1比特序列来表示的。
执行加密操作
的程序,就是将表示明文的比特序列
转换为表示密文的比特序列
,将现实世界中的东西映射为比特序列的操作称为编码
暴力破解
将所有可能的密钥全部尝试一遍,这种方法称为暴力破解。由于这种方法的本质是从所有的密钥中找出正确的密钥,因此又称为穷举搜索
异或
为了让大家理解比特序列运算的概念,我们介绍一下异或运算,异或一般用+和O组合而成的符号⊕
来表示。尽管名字看起来很复杂,但这种运算本身一点都不难。
1个比特的异或运算的规则如下:
shell
0 ⊕ 0 = 0
0 ⊕ 1 = 1
1 ⊕ 0 = 1
1 ⊕ 1 = 0
总结起来就是:相同比特异或为0,不同为1
如果是比特序列之间的异或,则只要对其中每个相对应的比特进行异或运算就可以了。
假设我们将 01001100 这个比特序列称为 A,将 10101010 这个比特序列称为 B ,那么A与B的异或运算就可以像下面这样逐一对各个比特进行计算。和加法运算不同的是,异或中不需要进位
。
markdown
01001100 ⊕ 10101010 = 11100110
A ⊕ B = 11100110
由于两个相同的数进行异或的结果一定为0,因此如果将A⊕B的结果再与B进行异或运算,则结果会变回A。从上面的例子中也能看出,0异或其他数字,得到的都是异或的那个数字。 也就是说,两个公式中的B会相互抵消。
markdown
A ⊕ B ⊕ B = A
可能大家已经发现了,上面的计算和加密、解密的步骤非常相似。
- 将明文A用密钥B进行加密,得到密文A⊕B
- 将密文A⊕B用密钥B进行解密,得到明文A
实际上,只要选择一个合适的B,也就是密钥,仅仅使用异或就可以实现一个高强度的密码。
一次性密码本-绝对不会被破译的密码
只要通过暴力破解法对密钥空间进行遍历,无论什么密文总有一天也都能够被破译。然而,一次性密码本却是一个例外。
一次性密码本是一种非常简单的密码,它的原理是:"将明文与一串等长的随机的比特序列进行异或运算"。
下面我们将明文 me 这个字符串通过 ASCII 码(理解为将字符转化为比特序列的一套规则)进行编码并产生一串比特序列。
markdown
m: 01101101
e: 01100101
01101101 01100101
在这里,明文被编码为一串长16比特的比特序列。
然后我们再来产生一个和明文长度相同的16比特的随机比特序列,这个序列就是密钥。01101011 11111010
下面我们将明文与密钥的比特序列进行异或运算,并得到一串新的比特序列,这次运算的结果也就是一次性密码本的密文。
markdown
01101101 01100101 ⊕ 01101011 11111010 = 00000110 10011111
这样产生的比特序列如果硬要显示在计算机上,则有可能像是乱码一样,因为密文通常不会被还原为字符,而是被作为二进制数据来处理。
上面提到过,用密文和密钥进行异或运算,就可以得到明文。
正如上面所讲到的那样,一次性密码本是一种非常简单的密码。如此简单的密码居然无法破译,这真是让人匪夷所思。
这里说的无法破译,并不是指在现实的时间内难以破译,而是指即便拥有一种运算能力无穷大的计算机,可以在一瞬间遍历任意大小的密钥空间,也依然无法破译。这里可能有些绕,这里无法破译指的是不知道破译的结果哪种是正确的,没有一个停止的时间点。
为什么呢?我们假设对一次性密码本的密文尝试进行暴力破解,那么总有一天我们会尝试到和加密时相同的密钥,也就能解密出明文me,这是毋庸置疑的事实。
然而下面这一点非常重要,即便我们能够解密出me这个字符串,我们也无法判断它是否是正确的明文。这是因为在对一次性密码本尝试解密的过程中,所有的16比特的排列组合都会出现,这其中既会包含像aa、ab、ZZ 这样的规则字符串,也会包含me、we等英文单词,还会包含号Ta、HY、#6等看不懂的组合。
由于明文中所有可能的排列组合都会出现,因此我们无法判断其中哪一个才是正确的明文(也就是用哪个密钥才能够正确解密)
一次性密码本是无条件安全的,在理论上是无法破译的。
那么一次性密码本为什么没有被使用呢,上面我们只谈了一次性密码本好的方面(对密码破译者来说是不好的方面),然而在现实中,几乎没有人应用一次性密码本,因为它是一种非常不实用的密码,原因如下:
最大的问题在于密钥的配送。因为一次性密码本是绝对无法破译的。接收者收到了发来的密文,要想进行解密,就必须使用和发送者加密时相同的密钥,因此发送者必须将密钥也发送,且该密钥的长度和密文是相等的。但这样就产生了一个矛盾,如果能够有一种方法将密钥安全地发送出去,那么岂不是也可以用同样的方法来安全地发送明文了吗?
另外是密钥的保存。由于密钥保护着明文的机密性,因此必须妥善保存,不能被窃听者窃取。不过,如果能够有办法安全保存与明文一样长的密钥,那不也就有办法安全保存明文本身了吗?也就是说,我们只是将"保护明文"这一命题替换成了"保护和明文一样长的密钥"而已,问题并没有得到实质性的解决。
另外是密钥的重用。在一次性密码本中绝对不能重用过去用过的随机比特序列,一次性密码本中的"一次性"也正是由此而来。这是因为作为密钥的比特序列一旦泄露,过去所有的机密通信内容将全部被解密(假设窃听者保存了过去所有的通信内容)
另外是密钥的同步。一次性密码本中还会产生发送者与接收者之间密钥同步的问题。当明文很长时,一次性密码本的密钥也会跟着变长。如果明文是一个大小为100MB的文件,则密钥的大小也一定是100MB。而且在通信过程中,发送者和接收者的密钥的比特序列不允许有任何错位,否则错位的比特后的所有信息都将无法解密。
最后是密钥的生成。在一次性密码本中,需要生成大量的随机数。这里的随机数并不是通过计算机程序生成的 为随机数,而必须是无重现性的真正随机数。
综上所述,一次性密码本是一种几乎没有实用性的密码。但是,一次性密码本的思路却孕育出了流密码。流密码使用的不是真正的随机比特序列,而是伪随机数生成器产生的比特序列。流密码虽然不是无法破译的,但只要使用高性能的伪随机数生成器,就能够构建出强度较高的密码系统。关于流密码我们将在后面详细讲解。
什么是DES
DES(Data Encryption Standard) 是一种对称密码。由于 DES 的密文可以在短时间内被破译,因此除了用它来解密以前的密文以外,现在我们不应该再使用 DES 了。
DES的加密和解密
DES 是一种将64比特的明文
加密成64比特的密文
的对称密码算法
,它的密钥长度是56比特
。
尽管从规格上来说,DES的密钥长度是64比特,但由于每隔7比特
会设置一个用于错误检查的比特
,因此实质上其密钥长度是56比特。
DES是以64比特的明文比特序列为一个单位来进行加密的,这个64比特的单位称为分组
。一般来说,以分组为单位进行处理的密码算法称为分组密码
,DES就是分组密码的一种。
DES每次只能加密64比特的数据,如果要加密的明文比较长,就需要对DES加密进行迭代(反复),而迭代的具体方式就称为模式
。关于模式我们会在后面详细探讨。
差分分析与线性分析
差分分析是一种针对分组密码的分析方法,其思路是:"改变一部分明文并分析密文如何随之改变"。理论上说,即便明文只改变一个比特,密文的比特排列也应该发生彻底的改变。于是通过分析密文改变中所产生的偏差,可以获得破译密码的线索。
此外,还有一种叫作线性分析,其思路是:"将明文和密文的一些对应比特进行异或并计算其结果为零的概率"。如果密文具备足够的随机性,则任选一些明文和密文的对应比特进行异或结果为零的概率应该为0.5。如果能够找到大幅偏离的部分,则可以借此获得一些与密钥有关的信息。
差分分析和线性分析都有一个前提,那就是假设密码破译者可以选择任意明文并得到其加密的结果,这种攻击方式称为选择明文攻击
。
以 AES 为代表的现代分组密码算法,在设计上已经考虑了针对差分分析和线性分析的安全性。
什么是三重 DES
现在 DES 已经可以在现实的时间内被暴力破解,因此我们需要一种用来替代 DES 的分组密码,三重 DES 就是出于这个目的被开发出来的。
三重DES(triple-DES)是为了增加DES的强度
,将DES重复3次所得到的一种密码算法,通常缩写为 3DES。
三重DES的加密机制如下:
markdown
第一次:DES密钥1 + DES加密
第二次:DES密钥2 + DES解密
第三次:DES密钥3 + DES加密
明文经过三次DES处理才能变成最后的密文。
由于DES密钥的长度实质上是56比特,因此三重DES的密钥长度就是 56×3 = 168比特
。
从上面我们可以发现,三重DES并不是进行三次DES加密(加密→加密→加密),而是加密→解密→加密的过程。
在加密算法中加入解密操作让人感觉很不可思议,实际上是为了让三重DES能够兼容普通的DES。当三重DES中所有的密钥都相同时,三重DES也就等同于普通的DES了。这是因为在前两步加密→解密之后,得到的就是最初的明文。因此,以前用DES加密的密文,就可以通过这种方式用三重DES来进行解密。也就是说,三重DES对DES具备向下兼容性。
如果所有密钥都使用相同的比特序列,则其结果与普通的DES是等价的。如果密钥1和密钥3使用相同的密钥,而密钥2使用不同的密钥(也就是只使用两个密钥),这种三重DES就称为DES-EDE2。EDE表示的是加密(Encryption)→解密(Decryption)→加密(Encryption)这个流程。密钥1、密钥2、密钥3全部使用不同的比特序列的三重DES称为DES-EDE3。
三重DES的解密
和加密正好相反,是以密钥3、密钥2、密钥1的顺序执行解密→加密→解密的操作。
markdown
第一次:DES密钥3 + DES解密
第二次:DES密钥2 + DES加密
第三次:DES密钥1 + DES解密
三重DES因其处理速度不高,除了特别重视向下兼容性的情况以外,很少被用于新的用途。
什么是AES
AES(Advanced Encryption Standard)是取代其前任标准(DES)而成为新标准的一种对称密码算法。
全世界的企业和密码学家提交了多个对称密码算法作为AES的候选,最终在2000年从这些候选算法中选出了一种名为 Rijndael 的对称密码算法,并将其确定为了AES。
AES的选拔过程是对全世界公开的。实际上,对密码算法的评审是由全世界的企业和密码学家共同完成的,这其中也包括AES竞选的参加者。换句话说,参加竞选的密码算法是由包括参加者在内的整个密码学社区共同进行评审的。一旦被找到弱点就意味着该密码算法落选,因此参加者会努力从各个角度寻找其他密码算法的弱点,并向其他参与评审的人进行证明。
像这样通过竞争来实现标准化
(standardization by competition)的方式,正是密码算法选拔的正确方式。由世界最高水平的密码学家共同尝试破译,依然未能找到弱点,只有这样才能够证明一种密码算法的强度。
什么是 Rijindael
Rijndael 是由比利时密码学家设计的分组密码算法,在AES的规格中,分组长度固定为128比特,密钥长度只有128、192和256比特三种。
前面我们介绍了DES、三重DES和AES等对称密码,那么我们到底应该使用哪一种对称密码算法呢?
首先,DES不应再用于任何新的用途
其次,我们也没有理由将三重DES用于任何新的用途,它会逐渐被AES所取代。
现在大家应该使用的算法是AES(Riindael),因为它安全、快速,而且能够在各种平台上工作。此外,由于全世界的密码学家都在对AES进行不断的验证,因此即便万一发现它有什么缺陷,也会立刻告知全世界并修复这些缺陷。