22

系列文章传送门:

  1. 网络协议 1 - 概述
  2. 网络协议 2 - IP 是怎么来,又是怎么没的?
  3. 网络协议 3 - 从物理层到 MAC 层
  4. 网络协议 4 - 交换机与 VLAN:办公室太复杂,我要回学校
  5. 网络协议 5 - ICMP 与 ping:投石问路的侦察兵
  6. 网络协议 6 - 路由协议:敢问路在何方?
  7. 网络协议 7 - UDP 协议:性善碰到城会玩
  8. 网络协议 8 - TCP 协议(上):性恶就要套路深
  9. 网络协议 9 - TCP协议(下):聪明反被聪明误
  10. 网络协议 10 - Socket 编程(上):实践是检验真理的唯一标准
  11. 网络协议 11 - Socket 编程(下):眼见为实耳听为虚
  12. 网络协议 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 协议的思路就是这样的。如下图:

    图比较长,整个过程最后的目标是生成在后续通信过程中使用的对称密钥,以及约定使用的加密算法。整体过程如下:

  1. 客户端明文发送 TLS 版本信息、加密套件候选列表、压缩算法候选列表等信息,另外还会发送一个随机数,在协商对称密钥的时候使用(你好,我想定外卖,但你要保密我点了什么。这是我的加密套路列表,还有一个随机数 A,你留着);
  2. 服务器返回 Server Hello 消息,告诉客户端,服务器选择使用的协议版本、加密套件、压缩算法等,还有一个随机数 B,用于后续进行密钥协商(你好,保密没问题,就按套路 2 来吧,我也给你一个随机数 B,你留着);
  3. 服务器给客户端证书;
  4. 客户端从自己信任的 CA 仓库中,拿 CA 的证书里面的公钥去解密服务器传来的证书。解密成功,说明外卖网站是可信的。这个解密过程,客户端可能胡不断往上追溯 CA、CA 的 CA、CA 的 CA 的 CA,直到一个授信的 CA 为止;
  5. 证书验证可信后,客户端会计算产生随机数字 Pre-master,发送Client Key Exchange,用证书中的公钥加密,再发给服务器;

    到此时,无论是客户端还是服务端,都有了三个随机数,分别是:A、B、Pre-master。通过这三个随机数,客户端和服务端可以产生相同的对称密钥。

    约定好对称密钥和加密算法,就可以用对称加密的形式进行加密通信了,后续的通信除了多了一步密钥校验的过程,HTTP 协议里的那些过程都不会少。

    不过上面的过程中只包含了 HTTPS 的单向认证,也就是客户端验证服务端的证书,这也是最常见的场景。不过在更加严格要求通信安全的情况下,也可以启用双向认证,双方互相验证证书。

    通过上面的整个过程,我们可以看出,HTTPS 协议并不是一个新的协议,它只是 HTTP 协议与一些加密算法的组合,用来保证通信的安全。

    虽然上面介绍的非对称加密方式,在现在看来是完美不可解的,但未来谁知道呢?正所谓“道高一尺魔高一丈”,加密安全路上永无尽头。

小结

  • 加密分对称加密非对称加密。对称加密效率高,但存在密钥传输的问题;非对称加密可以解决密钥传输的问题,但效率较低。
  • 非对称加密需要通过证书权威机构来验证公钥的合法性。
  • HTTPS 是综合了对称加密和非对称加密算法的 HTTP 协议。既保证了传输安全,也保证了传输效率。

参考:

  1. 百度百科 - htps 词条;
  2. 刘超 - 趣谈网络协议系列课;

北国风光
1.7k 声望279 粉丝

做一个靠谱的人,凡事有交代,件件有着落,事事有回音!