你知道吗?如果不是密码学的发展,可能计算机的出现还要晚很多年。 众所周知,图灵是计算机科学之父。图灵早年从事密码破解工作。在二战期间,图灵对破解德军 Enigma 密码机做出了巨大贡献,从而加快了二战结束的步伐。由于破解密码需要大量的计算工作,所以图灵参与了最早的电子计算机研发工作。最终图灵奠定了计算机科学的基础。
所以在某种意义上,可以说是密码学的发展加快了了计算机的产生。
为什么需要加密?
密码学源于解决消息传递过程中的安全问题。
我们可以思考下面的一个场景。上大学的小明给爸爸写信,让爸爸汇款1000块钱给他报补习班。在这个过程中接触到信件的人很多,如果被某个别有用心的人利用,就会产生严重的后果。比如下面几种情况:
1、信件中涉及小明的敏感信息,如身份证号。如果被接触到信件的人看到,可能会被拿去做一些非法的事情。
2、接触到信件的投递员小刚,看到信件内容后,起了贪心。他伪造了信件,修改了收款的账户。于是小明爸爸收到信件后给小刚汇去了100元钱。
小明为了避免上面的问题,于是决定亲手将信交给自己的父亲。这样是否就高枕无忧?并不是,此时出现了新问题。
3、小刚化妆成小明的父亲,骗过了小明,从而拿到了小明的信件。
一次简单的通信,就这样被搞成了谍战。其实这并不夸张。二战期间,每天都在上演着同样的戏码。以上三个问题是通信过程中必须要解决的安全问题:
- 信息保密问题
- 信息篡改问题
- 通信对象认证问题
密码学要解决的就是上面这三个问题。
密码系统
信息加密是指将信息转化为任何第三方都无法读懂,只有发送方和接收方能看懂的信息。例如暗号可以看作最简单的加密方式。如果存在一门外语只有通讯双方知道,那么将信息翻译成这种语言也算一种加密方式。当然,我们要聊的加密复杂的多。
密码系统是由算法+密钥所组成。明文和密钥是原材料,算法是加工的方式,产出就是密文。
我们都知道密钥是要保密的,那么密码算法是否也需要保密呢?这个问题常常会困扰初学者。事实上,试图通过对密码算法保密来提高安全性的行为(隐蔽式安全性)是非常愚蠢的。因为任何算法最终都会被破解,所以现在流行的密码算法都是公开的,从诞生之初就没想通过保密算法来提高安全。密码学中有一个原则:杜绝隐蔽式安全性。
密码算法要考虑的关键因素是让破解者难以通过明文、密文、以及其他信息推断出密钥或者缩小密钥的范围,从而暴力破解出密钥。
为了理解密码算法、密钥、破解这些概念,我们先看一个非常简单的密码系统----简单替换密码。
简单替换密码
简单替换密码系统中,我们为26个字母建立映射关系,例如s->a、c->d、h->n、o->x、l->y…… 26个字母被影射为另外的字母,那么一个明文的单词被加密后就无法认出了。例如school,按照上面的映射关系,就变成了adnxxy。
在这个密码系统中也存在密码算法和密钥。
密码算法:26个字母按照固定的映射关系做替换
密钥:26个字母的替换关系
如果想要破解密钥,也就是要找出26个字母的替换关系。a有26种替换可能,b有除a选择替换的字母之外的25种可能。以此类推,存在的替换关系有26x25x24……x1,约为2的88次方。如果计算机可以一秒尝试一亿个密码,运气差的话要尝试1200亿年。因此暴力破解是行不通的。
但是由于密码算法中,替换关系是稳定的,所以可以采用频率分析的方式破解密码。原理是明文中同一个字母出现的频率和密文中被替换的字母出现的频率一致。在英文中,字母出现的频率是相对稳定的。因此可以根据字母出现的频率推算出替换关系,也就是密钥。从而完成破解。
由此可见这种密码系统不安全的根源在于密码算法,该算法很容易让破解者推测出密钥,因此安全性极低。
对称密钥
密钥分为两类,对称密钥和非对称密钥(公钥密钥)。
对称密码指加密和解密使用同样的密钥。
非对称密码指加密和解密使用不同密钥。
我们思考一下,简单替换密码是对称密码还是非对称密码呢?简单替换的密钥是字母映射表,加密和解密使用同样的字母映射表,所以是对称密钥。
在计算机的世界里,机器直接操作的数据并不是文字,而是0和1组成的比特序列。我们所要加密的对象就是特定顺序的比特序列。
二进制的数字有一种运算叫做异或,运算符号 XOR。这种运算有一个特性,如果 A XOR B = C ,那么C XOR B =A。这个特性和加解密的过程十分相似,A 可以看作是明文,B 看作密钥,XOR 看作密码算法,C是加密后的密文。用密钥 B 可以将 C 还原为明文 A。
异或算法太简单,不能直接用作密码算法。不过我们所熟知的对称密钥 DES 和 AES 都是以异或运算为基础的。
DES
DES 曾经是 1977 年美国联邦信息处理标准中所采用的一种对称密码。曾经得到了广泛的使用。不过随着计算机算力的提升,DES 已经不再安全,可以在短时间内通过暴力破解。所以现在 DES 已经不在推荐使用。
DES 密钥长度为 64 比特,每次可以加密 64 比特的明文。如果明文长度大于 64 比特,就需要对明文比特序列进行分组,迭代加密,迭代的方式称为模式。
DES 的加密结构由 Horst Feistel 设计,由于图形化标示后像一张网,所以也称为 Feistel 网络。Feistel 网络中每次加密都要经过数轮。
Feistel 网络中,首先将要加密的 64 比特分成左右各 32 比特,右侧的 32 比特和轮函数及子密钥输出加密左侧用的比特序列。左侧32比特序列与其做 XOR 运算后,得到加密的密文。此时反转左右侧,重复操作一次后,全部64位比特都被加密。根据加密强度的需要,可以进行多轮操作。
大家可能会有问题,每轮只加密一半比特序列,是不是效率太低了?其实这是为了确保可解密性。
我们看看 DES 是如何解密的。为了简化问题,我们只进行一轮加密。此时我们不对调左右侧比特序列,再使用右侧32位比特+子密钥+轮函数计算出比特序列。这个比特序列其实和之前加密用的比特序列完全一样,原因是输入和算法一样。左侧加密过的32比特和此比特序列做 XOR 运算,由于 XOR 运算的特性,加密过的左侧32比特会被还原回原来的 32 比特,这时就完成了解密。
加密时无论轮次有多少、无论轮函数如何实现,通过逆向操作都可以正确解密。
三重 DES
由于 DES 已经可以被暴力破解,于是出现了三重 DES。三重 DES 其实就是将 DES 重复了三次。但是加密过程并不是加密、加密、加密,而是加密、解密、加密。加密过程中引入解密运算,是为了兼容 DES。试想如果三次运算的密钥是同一个,那么前两步加密解密后相当于什么都没做,仅第三步做了一次 DES 加密。
解密是逆向操作,通过解密、加密、解密三部运算完成三重 DES 的解密。
三重DES由于处理速度不高,除了兼容DES的场景,已经很少使用。
AES
AES(advanced encryption standard)的出现,正是为了取代 DES。AES 是新的对称密码算法。AES 算法是经过公开选拔所产生。这样彻底杜绝了隐蔽式安全性。最终,比利时密码学家 Joan Daemen 和 Vincent Rijme 开发的密码算法 Rijndael成为了 AES 标准。
AES 所支持的 Rijndael 密码算法,分组长度为 128 比特,密钥长度有 128、192、256比特三种选择。
AES 算法也有多个轮次,每轮次有如下四个步骤:
- SubBytes
- ShiftRows
- MixColumns
- AddRoundKey
SubBytes
类似于简单替换,将每个字节的值替换为另外的值。
ShiftRows
首先将明文以4字节为一行,转化为多行,也就是矩阵。每行按照一定规则向左平移
MixColumns
将矩阵的列,每4个字节为单位进行比特运算,转化为另外的4字节值。
AddRoundKey
将 MixColumns 后的数据与轮密钥进行 XOR 运算。
以上四步执行完后,一轮 Rijndael 加密就结束了。Rijndael 加密一般要进行 10-14 轮计算。
Rijndael 解密的过程则是相反的顺序:
- AddRoundKey
- MixColumns
- ShiftRows
- SubBytes
Rijndael 加密的过程有点像玩魔方。假如有种魔方,除了和普通魔方相同之处外,每个格子还写有文字。Rijndael 加密的过程和打乱这个魔方非常像。横着转几下,竖着转几下。除了打乱行、列,还对格子里的值做了替换以及 XOR 加密。
而 Rijndael 解密的过程就是还原魔方,只不过不但颜色要还原一致,魔方格子上的文字也要还原。 你是否担心会玩魔方的人很容易就能复原?由于AES中使用了密钥,所以即使精通AES算法,拿不到密钥也很难还原。
对称加密总结
切记不要试图自己开发加密算法,通过隐藏加密算法的方式来提高安全性。要杜绝隐蔽式安全性。DES 不应该再被用作新的用途。在一些需要兼容 DES 的场景下,可以使用三重 DES。没有特殊情况,我们都应该首选 AES。