网络协议 13 - HTTPS 协议:加密路上无尽头
系列文章传送门:
- 网络协议 1 - 概述
- 网络协议 2 - IP 是怎么来,又是怎么没的?
- 网络协议 3 - 从物理层到 MAC 层
- 网络协议 4 - 交换机与 VLAN:办公室太复杂,我要回学校
- 网络协议 5 - ICMP 与 ping:投石问路的侦察兵
- 网络协议 6 - 路由协议:敢问路在何方?
- 网络协议 7 - UDP 协议:性善碰到城会玩
- 网络协议 8 - TCP 协议(上):性恶就要套路深
- 网络协议 9 - TCP协议(下):聪明反被聪明误
- 网络协议 10 - Socket 编程(上):实践是检验真理的唯一标准
- 网络协议 11 - Socket 编程(下):眼见为实耳听为虚
- 网络协议 12 - HTTP 协议:常用而不简单
之前说了 HTTP 协议的各种问题,但是它还是陪伴着互联网、陪伴着我们走过了将近二十年的风风雨雨。现在有很多新的协议尝试去取代它,来解决性能、效率等问题,但它还还能靠着“多年的情分”活的滋润。然而,近些年,因为致命的安全问题,它不得不升级成 HTTPS 了。
就拿我们叫外卖来说,我们点外卖的数据包被黑客截获,然后在服务器回复你之前给你回复一个假消息:“好啊,你该付款了,把银行卡号、密码拿来。”,这时如果你真的把卡号和密码发给他,那你的钱包就真的危险了。
为了解决这些问题,我们给 HTTP 引入了加密,变成了 HTTPS。大家千万不要以为 HTTPS 是个新的协议,它实际上就是:
HTTPS = HTTP + SSL 层
这里的 SSL 层的主要工作就是加密。加密方式一般分为两种:对称加密和非对称加密。
这两种加密算法,对称加密要比非对称加密的效率要高很多,性能也好很多,所以交互的场景下多用对称加密。
对称加密
在对称加密算法中,加密和解密的密钥是相同的。也就是说,加密和解密使用的是同一个密钥。因此,使用者一定要做好保密功能,不能让第三方知道。
假设叫外卖的你和第三方约定了一个密钥 A,你发送请求的时候用 A 进行加密,外卖网站也用 A 进行解密,这样就算黑客截获了你们的请求,但是没有正确的密钥,还是破解不了。
看起来很好的解决了黑客的问题。但是这里又引入了一个问题,你和外卖网站怎么来约定这个密钥呢?如果这个密钥在互联网上传输,就必须还得用 B 密钥来加密,否则被黑客获取到 A,你们的交互还是不安全,而且,你们又怎么约定 B 呢?所以,只能通过线下传输。
线下传输的话,看过《肖申克的救赎》的博友应该知道,安迪越狱前给瑞德约定了一个地点,让他去那里拿一个信封,里面写着他的住处。
那我们和外卖网站也可以用这样的骚操作,偷偷约定时间地点,它给你一个纸条,上面写着你们两个的密钥,然后就用这个密钥在互联网定外卖。
打住打住,上面这个操作想想都不可思议,如果最初的互联网是这样发展的话,那相信肯定活不久。
相信你也发现了,只有对称加密,就会陷入密钥安全问题的死循环里,这时候,就需要非对称加密了。
非对称加密
在非对称加密中 ,加密和解密过程中使用两个不相同的密钥。一个是公开的公钥,另一个是谁都不给的私钥。公钥加密的信息,只有私钥才能解密,而私钥加密的信息,也只有公钥才能解密。
放到外面上面的叫外卖过程中,非对称加密的私钥由外卖网站保存,不会再网上传输,这样就保证了私钥的私密性。与之对应的公钥是可以在互联网上随意传播的,只要外卖网站把这个公钥给你,你们就可以安全的互通了。
还是来看我们点外卖的过程。我们用公钥加密,说“我要豆浆加油条”。黑客在中间截获了这个数据包,但是他没有私钥,没法解密数据,因此可以顺利到达外卖网站。而外卖网站用私钥把这个报文解出来,然后回复,“我知道了,你付款吧,给我卡号和密码”。
整个过程好像很安全,再也不怕黑客了。但是,先别太乐观,你的银行卡是安全了,但是外卖网站可还是有危险的。黑客有外卖网站的公钥,可以模拟发送“我要定外卖”这个信息。
为了解决这个问题,看来一对公钥私钥是不够的,客户端也需要有自己的公钥和私钥,并且客户端也要把自己的公钥给外卖网站。
这样,客户端给外卖网站发送信息的时候,用外卖网站的公钥加密,而外卖网站给客户端发送消息的时候,使用客户端的公钥。这样就算有黑客企图模拟客户端获取一些信息,或者半路截获回复信息,但是由于它没有私钥,这些信息它还是打不开。
说了那么多,相信你也发现了,非对称加密也会有同样的问题,如何将不对称加密的公钥给对方?这时有两种可行方式,一种是放在一个公网的地址上,让对方下载,另一种就是在建立连接的时候传给对方。
这两种方法也有相同的问题。作为普通网民,你怎么鉴别别人给你的公钥是对方的,而不是被黑客冒充的?要知道,每个人都是可以创建自己的公钥和私钥的,创建过程如下:
# bash
// 创建私钥:
openssl genrsa -out httpsprivate.key 1024
// 根据私钥获取公钥
openssl rsa -in httpsprivate.key -pubout -out httpspublic.pem
HTTPS 证书
可以看到,通过工具,我们可以很容易的创建公钥和私钥,那么黑客也是可以创建的,咱们怎么知道外卖网站传过来的公钥是不是真的就是外卖网站的呢?这时候,就需要第三方机构来当这个中间人了。
这就像我们的户口本一样,每个人都可以打印出来,说是真的户口本,但是去使用的时候,人家就只认有公安局盖章的户口本。这个由权威部门颁发的称为**证书(Certificate)。
HTTPS 证书里面应该有以下内容:
- 公钥:这是最重要的;
- 所有者:说明证书是属于谁的,就像户口本上的姓名和身份证号,来证明这个户口本是你的;
- 证书发布机构:看看你的户口本上有没有某某公安局的字样?
- 证书有效时间:这个和咱们身份证有效期是一个意思。
说完了证书的内容,就到了下一步,怎么获取证书?这就像家里添了个小公举,去哪里上户口呢?恐怕大家都知道去公安局。与之对应的,HTTPS 也有专门负责派发证书的机构,这个机构我们称为 CA(Certificate Authrity)。而证书则可以通过下面这个命令生成:
openssl req -key httpsprivate.key -new -out httpscertificate.req
将这个请求发给 CA,CA 会给这个证书“盖”一个章,我们称为签名算法。这个签名用到 CA 的私钥进行签发,来保证签名不被伪造。
签名算法大概是这样工作的:一般是对信息做一个 Hash 计算,得到一个 Hash 值,这个过程是不可逆的,也就是说无法通过 Hash 值还原回原来的信息内容。再把信息发出时,把上面得到的 Hash 加密后,作为一个签名和信息一起发出去。CA 给整数签名的命令是:
openssl x509 -req -in httpscertificate.req -CA cacertificate-pem -CAkey caprivate.key
这个命令会返回 Signature ok,而 httpscertificate.pem 就是签名过的整数。CA 用自己的私钥给外卖网站的公钥签名,这就相当于给外卖网站背书,形成了外卖网站的证书。我们可以通过下面这个命令查看证书内容:
openssl x509 -in httpscertificate.pem -noout -text
证书会显示以下内容:
- lssuer:证书颁发者;
- Subject:证书颁发给谁;
- Validity:证书期限;
- Public-key:公钥内容;
- Sinature Algorithm:签名算法
通过这种方式,我们访问外卖网站时,得到的不再是一个公钥,而是一个整数。这个证书里有发布机构 CA,你只要通过这个 CA 的公钥去解密外卖网站证书的签名,解密成功,Hash 对的上,就说明外卖网站的公钥是真实可信的。
上述整个过程中,都有一个前提,CA 是可信的。但是,我们又怎么确定 CA 的公钥就是对的呢?这就像有的人在偏远农村搞了个假公安局一样(应该没人这么干吧),我们怎么知道公安局是不是假的呢?然后我们就会想到,我去县公安局确认下当地公安局的信息不就好了。没错,CA 也是这么干的。
CA 的公钥也需要更牛的 CA 给它签名,然后形成 CA 的公钥。要想知道某个 CA 的证书是否可靠,要看 CA 的上级证书的公钥能不能解开这个 CA 的签名。这样追根溯源,直到全球皆知的几大著名 CA,我们称为Root CA,做最后的背书。正是通过这种层层授信背书的形式,保证了非对称加密模式的争吵运转。
除此之外,还有一种证书, 称为Self-Signed Certificate,就是自己给自己签名。这个就给人一种“我就是我,不一样的烟火,你爱信不信”的感觉,有兴趣的博友可以自行搜索了解。
HTTPS 的工作模式
上面说了对称加密和非对称加密的原理,我们知道了非对称加密在性能上远不如对称加密,那在 HTTP 中,能否将两者结合起来呢?例如,公钥私钥主要用于传输对称加密的密钥,而真正的双方大数据量的通信都是通过对称加密进行。
是的,HTTPS 协议的思路就是这样的。如下图:
图比较长,整个过程最后的目标是生成在后续通信过程中使用的对称密钥,以及约定使用的加密算法。整体过程如下:
- 客户端明文发送 TLS 版本信息、加密套件候选列表、压缩算法候选列表等信息,另外还会发送一个随机数,在协商对称密钥的时候使用(你好,我想定外卖,但你要保密我点了什么。这是我的加密套路列表,还有一个随机数 A,你留着);
- 服务器返回 Server Hello 消息,告诉客户端,服务器选择使用的协议版本、加密套件、压缩算法等,还有一个随机数 B,用于后续进行密钥协商(你好,保密没问题,就按套路 2 来吧,我也给你一个随机数 B,你留着);
- 服务器给客户端证书;
- 客户端从自己信任的 CA 仓库中,拿 CA 的证书里面的公钥去解密服务器传来的证书。解密成功,说明外卖网站是可信的。这个解密过程,客户端可能胡不断往上追溯 CA、CA 的 CA、CA 的 CA 的 CA,直到一个授信的 CA 为止;
- 证书验证可信后,客户端会计算产生随机数字 Pre-master,发送Client Key Exchange,用证书中的公钥加密,再发给服务器;
到此时,无论是客户端还是服务端,都有了三个随机数,分别是:A、B、Pre-master。通过这三个随机数,客户端和服务端可以产生相同的对称密钥。
约定好对称密钥和加密算法,就可以用对称加密的形式进行加密通信了,后续的通信除了多了一步密钥校验的过程,HTTP 协议里的那些过程都不会少。
不过上面的过程中只包含了 HTTPS 的单向认证,也就是客户端验证服务端的证书,这也是最常见的场景。不过在更加严格要求通信安全的情况下,也可以启用双向认证,双方互相验证证书。
通过上面的整个过程,我们可以看出,HTTPS 协议并不是一个新的协议,它只是 HTTP 协议与一些加密算法的组合,用来保证通信的安全。
虽然上面介绍的非对称加密方式,在现在看来是完美不可解的,但未来谁知道呢?正所谓“道高一尺魔高一丈”,加密安全路上永无尽头。
小结
- 加密分对称加密和非对称加密。对称加密效率高,但存在密钥传输的问题;非对称加密可以解决密钥传输的问题,但效率较低。
- 非对称加密需要通过证书和权威机构来验证公钥的合法性。
- HTTPS 是综合了对称加密和非对称加密算法的 HTTP 协议。既保证了传输安全,也保证了传输效率。
参考:
- 百度百科 - htps 词条;
- 刘超 - 趣谈网络协议系列课;