假设你要将一份机密的文档通过互联网发送给你的朋友老王,你可能会想到先将文档加密之后再发给他。不论你使用的是对称加密,还是非对称加密,首先都需要与老王沟通并确定加密方式,以及加密文档用的密钥。

假若你使用对称加密方式,密钥显然要告知老王,不然他无法解密。假若你使用的是非对称加密,比如RSA,那么你得知道老王的公钥,用来加密文档。所以你们怎么通过不安全的互联网来协商加密方式呢?

1. 仅使用对称加密

假若你仅仅只使用对称加密的话,那这份机密文档恐怕是无法安全传输了。因为对称加密双方都使用同一份密钥,要协商这个密钥的话,则必须要将这份密钥加密之后再传输,不能让第三方知道。这样一来就要先协商一个新的密钥,用新密钥来安全地传输这份密钥,从而安全地传输机密文件。但是新密钥又得安全传输,所以就要无限地递归下去了。

2. 使用非对称加密-存在中间人攻击

既然不能只用对称加密,那么必须用到非对称加密了。让老王把他的公钥发过来,不就可以直接加密文档了吗,公钥公开传输不会影响密文的安全性啊。

但是有一个问题,老王的公钥是用明文传给你的,这就有被第三方监听的可能。比如在你和老王通信的信道上有一个间谍,他能监听以及修改你和老王之间传输的所有数据。

当老王传输公钥给你时,他立即将公钥截获,然后把他的公钥发给你。你用间谍的公钥加密信息之后,满心欢喜地把密文发给老王。却不知间谍悄悄截获密文之后,使用他的私钥解密了文档,然后用老王的公钥重新加密了文档,再发给老王。老王收到密文之后可以成功地用他的私钥解密,但是你们并不知道原文件已经被间谍窃取到了。这就是所谓的中间人攻击(MITM

所以问题的根源在于,如何确保你收到的公钥是就是老王的,而不是第三方攻击者的?

3. 证明你是你-第三方机构介入

所以现在要防止老王发给你的信息被修改。目前防止信息被修改的方法一般是使用密码散列函数,比如使用MD5来计算信息摘要。往往在文件的下载页面会提供其MD5值,当文件下载完成后,再计算其MD5值并与下载页面提供的值相比较,若相同,则说明文件没有被篡改。

既然是这样,老王可不可以弄一个网站,上面挂着他公钥的MD5值,等你得到公钥之后再比较一下?答案显然是不行的,老王把MD5值挂到网页上等你来访问,其实等同于他把公钥以及MD5值一起发给你。间谍既然能修改公钥,那么他也能在你访问MD5值所在网页时把它修改成自己公钥对应的MD5值。

看来目前老王是没办法自己证明老王是老王了。一般碰到“证明我是我”的问题,常用的解决方案是请一个长者来证明一下。比如西游记中的真假美猴王,请如来佛祖出来辩一辩不就行啦。

同样的,为了证明老王发来的公钥就是老王的,我们可以用第三方权威机构的私钥给老王的公钥的MD5值进行加密,私钥加密后的值只有对应的公钥可以解开。但是间谍并没有权威机构的私钥,如果用他自己的私钥加密篡改后信息的摘要,在接收方用权威机构的公钥进行验证时,就会解密失败,进而发现信息被篡改。权威机构的公钥一般是预置在操作系统中的,你、老王以及间谍都能获取到。

4. 使用数字证书-CA颁发并签名

这次老王不仅要把他的公钥以及用权威私钥加密后的信息摘要发给你,而且还需要把权威机构的信息一并发给你,好让你在接收之后使用对应的权威公钥来解密。因为权威机构不仅一家嘛,西游里不还有玉帝跟如来么。

所以老王为了证明他自己,他得向Certificate_authority(数字证书认证机构)申请一张数字证书,证书中包含了老王的基本信息、老王的公钥类型、CA的基本信息、摘要算法、以及使用CA的私钥加密后的摘要。加密后的信息摘要称为数字签名

数字证书中最重要的是数字签名。如果删掉了数字签名,那么剩余的信息就可以被间谍随意地更改。数字签名即为信息摘要的加密,使用私钥加密确保了信息的可靠性,对信息摘要加密确保了信息的完整性

当你收到老王发给你的证书后,先按照证书中的摘要算法计算除了数字签名之外的信息摘要,然后用CA的公钥解密数字签名,倘若计算所得摘要与解密所得摘要相同,则表明证书没有被篡改。也就证明了老王是老王。

5. 发送密文-交换密钥

有了老王的公钥之后,你就可以用老王的公钥加密那份机密文件了,老王收到密文之后用他的私钥解密即可。

但是由于非对称加密的速度比较慢,一般是还是得用对称加密来加密文件,只不过是传输之前先用非对称加密来协商一下对称加密的方法以及其密钥。密钥交换的过程可以使用RSA来加密,也可以用其它的密钥交换算法,如Diffie–Hellman key exchange

好啦,你收到证书之后,在老王公钥加密的基础上与他进行了简单的沟通,确定了一种对称加密的方式,也把密钥发给他了。然后你就愉快地用对称加密把机密文件成功地发到他手上了。(此刻,间谍一脸懵逼)

6. 后记

问:RSA的公钥和私钥到底哪个才是用来加密和哪个用来解密?

既然是加密,那肯定是不希望别人知道我的消息,所以只有我才能解密,所以可得出公钥负责加密,私钥负责解密;同理,既然是签名,那肯定是不希望有人冒充我发消息,只有我才能发布这个签名,所以可得出私钥负责签名,公钥负责验证。 https://zhihu.com/question/25912483/answer/46649199

(完)

Wiki:

References: