不管是哪加密方式,不论它在刚出现时宣称有多么牢不可破,随着时间的迁移,它总会暴露出弱点,从一个强大的加密方式变成一个较弱的加密方式。就算目前所使用的那些还没有被破解的加密方式,在不断升级的CPU时钟频率前提下,暴力破解所需的时间也越来越短了。
在加密算法的发展过程中,有很多算法都已经被破解或被证明不够安全,唯有一种加密算法一直存在了93年。这种算法叫做一次性密钥(one-time pad)。在1917年, Gilbert Vernam开发了一种叫做Vernam Cipher 的加密方法,使用电传技术,通过打有密钥的纸带进行数据加密和解密。结果便出现了当时最强的对称加密技术。
美国陆军上尉Joseph Mauborgne注意到,这是真正随机产生的密钥,不会有任何重复的可能,因此Vernam cipher可以做到更强大的效果。于是,基于纸带密钥的方法,在一沓纸上印有随即字母或数字,作为密钥的加密算法出现了。相同的一沓纸可以给两个人用,每个页面上的每个字符只能用一次(每张纸上的字符或数字用完,则销毁该密码纸),这种方式可以避免敌人通过枚举法暴力破解信息。由于这种分法密钥流数据的技术是基于可销毁的纸张的,因此也被认为是一次性密钥。
信息理论之父Claude Shannon曾经通过数学方法,证明这种一次性密钥如果使用得当,是无法被破解的,而所谓的使用得当,是指及时销毁所使用的密钥页,即使对方拿到了密码本的其余部分,也无法进行解密。同样的理念也可以用于数字系统,但是要确保计算机具有足够的安全措施以及全面的考虑,防止黑客入侵一次性密钥系统。比如,一些昂贵的数据恢复系统会将已删除的文件恢复,其中就有可能恢复那些一次性的密钥文件。因此如果使用数字化的一次性密钥系统,就要确保所删除的密钥文件是被彻底删除,无法恢复的。一次性密钥加密方式有时候非常不方便,因此现在很少有人在用这种加密方式。而正是由于这种不便性,我们实际需要的是一些理论上有些弱的加密方式,比如AES/Rijndael 以及Twofish 。一次密钥的不方便性在于:
由于一次性密钥是一种对称加密方式,进行加密通信的双方需要拥有完全一样的密钥数据。而在某些环境下,这种条件是无法实现的,因为要想让双方都拥有这个密钥,就意味着必须有一种足够安全的方式让双方共享或传递密钥数据,而如果有了这样的安全环境,也就不需要再使用一次性密钥了。而一般来说通过物理方式传递密钥(比如亲手交给对方)才能实现一次性密钥的优势。
一次性密钥必须和所加密内如一样长。这意味着,如果你要对一个3GB的文件进行加密,就需要有一个3GB的一次性密钥。
相同的一次性密钥只能在两人间保存,如果超过两人知晓这个密钥,就不再安全了。比如,如果在多个人之间传送不同的信息,并且不能让接受者获知其它人所接受的信息内容,只用一个相同的密钥是完全达不到加密效果的。相反,如果采用非对称的加密方式,我们就只需提供一个唯一的公钥给人们,每个人都通过自己的私钥对数据进行加密解密,他们彼此之间是无法获知对方所加密的信息内容的,除非私钥被盗取或者通过日益强大的计算机系统经过暴力破解出来。这是因为当信息被公钥加密后,只有相关的私钥才可以将其解密。
重复使用一次性密钥存在潜在的安全风险,因为它面临着已知明文漏洞。Kerckhoffs的理论是,保证一次性密钥系统安全的前提是保证密钥安全,但是在米加密信息和明文信息共存的时候,可以倒推出这个一次性密钥。当然,如果每一段密钥都仅使用一次,那么安全性仍然没有问题,因为即使“敌人”同时获取了秘文和明文,并破解出了密钥,那这段密钥也是已经被遗弃的密钥,对于其它信息的破译毫无用处。而如果密钥被重复利用,那么以获取的明文信息就可以成为破解新加密信息的一个重要工具。这就是为什么这种加密系统被称为“一次性”密钥系统。
当使用过一次性密钥后,不能再使用这个密钥对其它要发送的数据进行加密。如果通信的双方分别位于地球的两端,那么这种通信方式会让人抓狂。另外还有其它一些因素也使得一次性密钥系统在某些环境下变得毫无实用性。但是这也给了我们一个理论知识,让我们能明白那些理论上较弱的密钥系统为什么还那么重要。
一次性密钥系统的工作方式很简单。它只是简单的对两组数据进行运算,比如两个字母或两个数字,并通过运算得出新的加密数据。而这个运算是针对待加密数据中的每一位数据的。运算过程很简单,一次一位数据。比如 XOR运算就可以用来进行这样的加密。我们举个最简单的例子,使用XOR运算对二进制数列进行加密:
首先,你需要一段信息。假设我们把“short”这个词作为信息,它确实不长。
接下来把这段信息转换成二进制形式。我们可以使用ASCII编码来转换 “short”这个词,转换后会得到下面这一串二进制信息:
0111001101101000011011110111001001110100
接下来你需要一个和上面二进制串长度完全一致的密钥。在这个例子中,我们可以使用下面这串二进制字符作为密钥:
0110010101101010001110010010011101100100
最后,我们将这两组字符串进行XOR 运算,基本上就是一个简单的减法。也就是说,信息中第一个字符是0,密钥的第一个字符也是0,那么0 - 0 = 0。同样,信息中第二个字符是1,密钥的第二个字符也是1, 1 - 1 = 0。接下来都是这样计算,计算中除了0外,还可能出现1 或 -1。此时对结果取绝对值,即不论1还是-1,均作为1。其运算过程和结果如下:
0111001101101000011011110111001001110100
0110010101101010001110010010011101100100
----------------------------------------
0001011000000010010101100101010100010000
当然,由于我们对结果的二进制串没有进行ASCII转换,因此很难看出它到底被加密成了什么样子。在电脑上进行ASCII编码很容易,手动编码则很麻烦,而对于数字编码,通过手动编码还是比较容易的。一次性密钥系统的核心算法显然是相当简单的。只要围绕这个核心算法,设计加密软件的其余部分,并找到合适的密钥使用方法,那么这个新的加密软件就是真正安全的。