对称加密
在之前的章节中, 我们知道了 Alice 和 Bob 为了保证他们之间消息的私密性, 他们对消息进行了加密. 并且, 我们还注意到一点, 就是 Alice 和 Bob 之间的加解密采用了相同的密匙. 我们统称这种加密和解密采用相同密匙的方式为 对称加密 symmetric encryption.
非对称加密
现在 Alice 有一份文件, 她使用对称加密的方式对文件进行了加密, 对应的也有一个密匙. 如果 Alice 希望将加密文件分发给不同的人, 那么她也需要将对应的密匙告诉不同的人:
- +-----------------> P1
- |
- | +---------------> P2
- | |
- +----+-++ +------------> P3
- | Key1 |
- +----+-++ +------------> P4
- | |
- | +---------------> P5
- |
- +-----------------> P6
现在 Alice 有非常多的文件需要加密, 那么她就需要生成非常多的密匙(Key1, Key2, Key3, ...). 于是, Alice 不得不对在本地对非常多的密匙进行妥善的保管. 不过, 即使她非常小心, 由于她将一把密匙告诉了不同的人, 其实也增加了密匙被窃取的可能性. 于是科学家就开始寻找一种方式来改善这种局面.
经过探索, 科学家们发现了另一种加密方式, 称为非对称加密 asymmetric encryption. 这种加密方式使用两把密匙, 称为 公匙 和 私匙. 公匙和私匙之间有一个奇妙的关系, 就是公匙加密的内容, 只可以使用与其对应的私匙解密; 反之, 私匙加密的内容, 只可以使用与之对应的公匙进行解密.
在使用非对称加密前, Alice 和 Bob 各自生成一对公匙和私匙, 然后只把各自的公匙交给对方, 各自把自己的私匙妥善保管起来, 看起来像是这样:
- +--------------+ +--------------+
- | | | |
- | Public-key1 | | Public-key2 |
- | Private-key1 | | Private-key2 |
- | | | |
- +------^-------+ Public-key1 +------^-------+
- | +--------------------------------> |
- + +
- Alice <--------------------------------+ Bob
- Public-key2
- +--------------+ +-------------+
- | | | |
- | Public-key2 | | Public-key1 |
- | | | |
- +--------------+ +-------------+
然后, 在 Alice 给 Bob 发送信息前, 她使用 Bob 给她的公匙将信息加密, Bob 接收到密文之后, 使用自己的私匙解密; Bob 给 Alice 发送信息前, 使用 Alice 给他的公匙将消息进行加密, 然后 Alice 在接收到密文后, 使用自己的私匙解密. 看起来像是这样:
- M1
- ^
- |
- +------+-------+
- | |
- | Private-key2 |
- | |
- +------^-------+
- |
- +---->M1 Public-key2-M1 +
- + +--------------------------------->
- Alice Bob
- <---------------------------------+ +
- + Public-key1-M2 M2 <------+
- |
- +------v-------+
- | |
- | Private-key1 |
- | |
- +------+-------+
- |
- v
- M2
如果我们希望和别人通信, 我们就将自己的公匙给他, 他使用我们的公匙加密信息产生密文, 而我们使用自己妥善保管的私匙对密文进行解密. 由于上面提到的公匙和私匙产生密文的唯一对应的特性, 任何使用你的公匙加密的信息, 只有你私匙才可以解密. 这样通过将加密和解密的密匙进行分离, 我们不必将解密密匙告诉别人, 从而提高加密的安全性.
数字签名
非对称加密可以用来对信息进行签名."签名", 故名思议就是在我们写完一封信时, 通常会在信的末尾处留下自己的签名, 签名也是一个信件来源者的身份标识信息.
为了使用数字签名, 首先 Alice 和 Bob 需要这么做:
首先 Alice 和 Bob 必须面对面的交换各自的公匙, 这样就可以确保相互得到的公匙是合法的. 然后他们之间约定好说, 消息的结尾部分将是各自的签名.
在其中一方给对方发送消息时, 比如 Alice 给 Bob 发送消息. Alice 要先对发送的信息运用摘要算法得出一串摘要信息. 摘要算法可以算出一段给定信息的摘要内容, 并且消息内容和消息的摘要内容是唯一对应的.
在得出了消息的摘要之后, Alice 使用自己的私匙对摘要进行加密, 为了方便描述, 我们称结果为 "加密摘要".
最后 Alice 将加密摘要放到消息的结尾处, 和原先想要发送的内容一起发送给 Bob. 到这里, Alice 完成了对自己信息的签名. 我们可以看到, 签名的过程实际就是使用自己的私匙对要发送的消息的摘要进行加密.
Bob 接收到消息后, 根据事先的约定, 他知道消息是分为两部分的, 一部分是实际的消息内容, 另一部分是结尾的加密签名. 于是他找出结尾处的加密签名, 并对其使用 Alice 的公匙进行解密. 对加密签名进行解密运算后将会得到一串信息, 根据公匙和私匙的唯一对应关系, 以及消息摘要和摘要结果的唯一对应关系, 如果消息是 Alice 发送的, 那么解密后的内容必然是 Bob 接收到的实际信息的摘要.
于是, Bob 对实际的消息内容运算摘要算法(与 Alice 相同的摘要算法), 得出实际的消息的摘要信息. 将这一步的摘要信息与上一步对加密签名进行解密后得到的摘要信息对比, 如果相同, 就说明消息是 Alice 发送的.
数字证书
通过数字签名, 我们可以验证的消息来源的合法性以及完整性. 合法性是通过私匙和公匙的唯一对象关系来确定的, 而消息和其摘要结果的唯一对于关系又可以确定消息的完整性. 在上一节的使用数字签名的例子中, 一个非常重要的注意点就是, Alice 和 Bob 必须确保相互之间公匙的合法性. 对于窃听者 Eve 来说, 他可以在 Alice 给 Bob 发送公匙时替换成自己的, 这样 Bob 接收到的公匙实际是 Eve 的, 但是 Bob 以为是 Alice 的; 同时 Eve 又将 Bob 发给 Alice 的公匙替换成自己的, 这样 Alice 以为公匙是 Bob 的, 这样就完成了中间人攻击.
于是, 需要有一种方式可以证明 Alice 接收到的证书是 Bob 的, 而不是 Eve 的. 这就有了数字证书的概念. 联想一下在实际生活中, 表示个人身份的工具就是身份证, 身份证是由户口所在地的派出所进行派发的. 数字证书的工作方式也是类似的.
合法的数字证书是由 CA(Certificate Authority) 机构进行签发的. 换句话说, CA 机构是一个证书的颁发机构, 它并不是只有一个, 它们之间的层次结构可以使用树形结构进行描述, 位于顶层的是根 CA, 它下面有由它授权的子 CA:
+------+
| 根 CA |
- +---+--+
- |
- +-----------+------------+
- | |
- | |
- +--v---+ +---v--+
| 子 CA | | 子 CA |
+------+ +------+
CA 机构也有一对自己的公匙和私匙. 签发的过程就是你去 CA 机构的网站上, 填写自己的公开身份信息 (比如公匙) 之后, CA 机构会使用自己的私匙将这些信息进行数字签名, 你可以想象一下, 就好比是一张纸, 上面写着两部分内容, 一部分是你的公开身份信息, 另一部分是 CA 对你的身份信息的数字签名(将你的身份信息进行摘要, 对摘要结果使用 CA 的私匙进行加密得出的内容).
在对计算机的使用中, 常常需要验证文件来源的合法以及完整性, 比如在安装软件的时候, 软件安装程序将会验证那些需要被安装的软件的数字证书. 软件安装程序在验证数字证书的时候, 必须知道 CA 机构的公匙(称为 CA 证书), 因为摘要是用 CA 的私匙加密的. 对于 CA 证书, 现在的操作系统中都有一个专门的地方去存放它们, 而且在操作系统安装完成之后, 就已经预置了一些知名的 CA 证书了.
讨厌的 Eve
现在 Eve 切断了 Alice 和 Bob 的直接通信, 然后分别伪装成 Alice 和 Bob 其中一个和另一通信. 比如 Eve 伪装成了 Bob, 当 Alice 对 Bob 开始协商密匙时, 她实际是在和 Eve 进行协商, 协商好密匙之后, 她原本期望对 Bob 发送的消息实际发送给了 Eve, 因为密匙是她和 Eve 之间生成的, 所以消息对 Eve 而言是没有隐私的.
可以通过这个图去理解:
- M1 C1M1=>C2M1 M1
- C1 C2
- Alice +------------------> Eve +------------------> Bob
- M1 C1M2<=C2M2 M2
- C1 C2
- Alice <------------------+ Eve <------------------+ Bob
上图中, Alice 发出消息到 Bob 接收到的过程为:
M1 是 Alice 发给 Bob 的明文
C1 是 Alice 和 Eve 之间的密匙
于是 Eve 接收到 Alice 的密文为 C1M1
Eve 将 C1M1 解密, 会得到 M1
C2 是 Eve 与 Bob 之间的密匙, 然后 Eve 将加密信息 C2M1 发送给 Bob
Bob 对 C2M1 使用他和 Eve 之间的密匙 C2 进行解密, 得到了最初有 Alice 发送的 M1
逆过程略.
这就是熟知的中间人攻击 man-in-the-middle attack.
浏览网站
在浏览器访问一个网站的时候, 它首先会向网站请求其数字证书, 网站在接受到浏览器的请求后, 会将数字证书返回给浏览器. 浏览器在验证访问的网站的合法性时:
浏览器首先使用其自带的一些 CA 证书 (浏览器一般自带了一些 CA 证书, 而不是直接使用系统中预装的) 对网站回传的数字证书进行验证, 验证这个证书是由合法的 CA 颁发的.
如果这个证书是由合法的 CA 机构颁发的, 再验证证书中的公开信息 (比如域名) 与现在访问的网站的 IP 是否一致.
这样就可以很大程度上防止中间人攻击, 因为我们假定当前使用的 DNS 服务器具有有效的安全措施, 而实际上如果你使用的是 ISP 推荐的 DNS 服务器的话, 那么你的安全性还是有保障的.
我们一定要确保安装的 CA 证书是合法的, 换句话说, 我们只有在确保了 CA 是我们可以信赖的情况下, 才可以安装它. 假设有网站 A, 它证书中的 "域名 - IP" 信息为 example.com - 123.456.789.000 证书的颁发机构是 CA1. 如果 CA1 没有原则地颁发了另一个证书, 其中的 "域名 - IP" 对应的信息为 example.com - 000.123.456.789, 那么实际上就给 Eve 使用 000.123.456.789 来完成中间人攻击造成了契机. CA 机构在给网站颁发证书时的原则就是, 对于一个已经颁发了证书的域名, 不可以将那个域名再对应到其他的 IP:
比如我们现在知道一个合法的网站 A, 它的证书应该是 example.com - 123.456.789.000
我们在浏览器中输入了域名 example.com. 浏览器根据当前的 DNS 环境 (已被 Eve 修改) 得知域名 example.com 被指向到了 000.123.456.789, 但是浏览器此时并不能意识到危险, 于是它浏览器向 000.123.456.789 这个机器请求网站的证书
网站回传的证书, 证书中有它一个伪装信息 example.com - 000.123.456.789, 根据 CA 的证书颁发原则, 它是不能颁发这样的证书的. 但是我们假设 CA 此时颁发了这样一个证书
浏览器接收到网站回传的证书后, 它开始验证签名
是否是 CA 颁发的? 是
证书信息和当前访问的是否一致? 是
于是浏览器就不能发现网站地址被篡改的情况了, Eve 则可以顺利的借助 000.123.456.789 在我们和我们实际期望访问的网站之间展开中间人攻击了
来源: https://juejin.im/post/5c4005b55188255a2346e9f3