JackHttp -- HTTPS 为什么是安全的?

如果你还不清楚 JackHttp 是什么,请戳这里!!!
阅读本文你将弄明白如下内容:

  • HTTP 为什么是不安全的
  • 什么是 HTTPS?
  • SSL/TLS 在网络分层中所处的位置
  • HTTPS 与 HTTP & SSL/TLS 之间的关系
  • HTTPS 为什么是安全的
  • HTTPS 连接流程
  • 分析 HTTPS 真的一定安全吗?
文章前部分理论居多,但很重要。
ok,我们今天依旧带着问题开始今天的内容。
什么是 HTTP? HTTP 定义的是一个客户端和服务器端通信的规范和标准。
如果你想具体了解什么是 HTTP ,可以阅读JackHttp – 从原理来理解 HTTP
HTTP 为什么不安全?
要弄清楚 HTTPS 为什么是安全的之前,首先我们得清楚 HTTP 为什么是不安全的,主要是2个原因。
1. HTTP 的传输是明文的。
2. HTTP 的传输过程中发生窃听或篡改。
再我们网络传输过程中, 为了遵守 HTTP, 我们的每一个请求都会被转换成报文,然后再进行传输,而我们的报文数据不是说能"嗖"的一下直接传输到对方服务器,中间会经过 中间代理服务器、路由器、wifi热点、通信服务运营商等 多个物理节点,这些节点会依次按顺序接收数据,并原封不动的传输到下一节点。
而由于 HTTP 是明文的,这些节点能清楚的看到我们每一个报文所发的原始数据(POST 请求时 Body 内容虽然不会被显示出来,但使用抓包工具也能获取到)。如果中间节点有坏人的话,他可以把我们的报文数据修改后,在传给下一节点。这样服务器在接收到数据的时候,就会拿到一个被篡改后的数据。
就算再中间节点中不发生篡改,单纯的窃听也是非常危险的,中间节点可以对我们的敏感数据进行记录,导致用户的隐私被泄露。
什么是 HTTPS? 那么为了解决 HTTP 不安全两个原因,大家想到两个思路,第一个思路是修改网络框架,让数据传输时不经过中间层或者只经过可靠的中间层。这种思路确实可以解决问题,但显然工作量太大,网络框架发展至今,要推翻重来不是闹着玩的。
于是就衍生出了第二种思路,既然 HTTP 是明文传输的,那么对 HTTP 传输的内容进行加密不就行了吗?这样中间节点就算看到数据,也没用啊,他看不懂,并且因为他看不懂,他也没办法篡改数据,监听的数据也将没有意义,这样不就完全规避了 HTTP 的弊端,达到安全了吗?
那么为什么还要引入 HTTPS 呢,要知道任何一个新的技术都需要经过 初版 -> 大众接收 -> 大众使用 -> 迭代 -> 推广 -> 迭代 -> 迭代 -> … -> 稳定 这样一个过程,会伴随着漫长的更换周期与兼容性遗留问题。能用当前技术解决问题的情况下,尽量不要选用新技术,来维持软件的稳定性。
其实 HTTPS 并不是什么新技术,也不是什么新的协议,他就是这么干的,再 HTTP 报文数据传递给 TCP 之前,也就是 HTTP 之下 TCP 之上的一个协议层增加了一个 安全层来对数据进行加密,同时会对服务器身份进行验证。
结论:由于 SSL 是基于 HTTP 之下 TCP 之上的一个协议层,是基于 HTTP 标准并对 TCP 传输数据时进行加密的,所以把数据从 HTTP 层经过 SSL/TLS 加密后再送达 TCP 之前的整个过程称之为 HTTPS 。既 HTTPS 是 HTTP+ SSL/TLS 的简称。
拓展:HTTPS 在数据送达 TCP 之前,会在安全层中进行 SSL/TLS 安全连接,其中连接过程会对服务器身份进行认证。也就是说要搞明白 HTTPS 为什么是安全的,我们必须得弄明白如下两个问题:
1、 SSL/TLS 是什么?
2、SSL/TLS 安全连接阶段是如何对数据进行加密以及身份验证的。**
什么是 SSL/TLS?
通过 HTTPS 的介绍我们清楚了 SSL 是基于 HTTP 之下 TCP之上的一个协议层,是基于 HTTP 标准并对 TCP 传输数据时进行加密的。那么什么是 SSL,什么又是 TLS 呢?
SSL (Secure Socket Layer ) 安全套接层
是 基于 HTTPS 下的一个协议加密层 ,最初是由网景公司(Netscape)研发,后被IETF(The Internet Engineering Task Force - 互联网工程任务组)标准化后写入 RFC(RFCRequest For Comments ),RFC 是互联网技术的规范!了解 RFC
TLS (Transport Layer Security) 安全传输层
由于 HTTPS 的推出受到了很多人的欢迎,在 SSL 更新到 3.0 时,IETF 组织对 SSL 3.0 进行了标准化,标准化后 IETF 对 SSL 进行更名为 TLS(Transport Layer Security)安全传输层协议并正式发布 TLS 1.0 版本,可以说 TLS 就是 SSL 的 3.1 版本或者说是 4.0 版本。
并同时发布 “RFC2246-TLS加密协议详解”,如果想更深入的了解 TLS 可以戳这里,传送门 ,在搜索栏搜索“RFC2246”下载 RFC 文档查看。
总结成网上的一张图,引用自百度:
JackHttp -- HTTPS 为什么是安全的?
文章图片

HTTPS 安全连接流程(重点) 弄清楚 HTTPS 与 HTTP & SSL/TLS 之间的关系之后且我们清楚了 SSL/TLS 安全层目的是对数据进行加密同时对服务器身份进行验证的,以此来达到数据传输安全。因此我们要了解 HTTPS 为什么是安全的,既需要弄明白 SSL/TLS 是怎么对数据进行加密和身份验证的。
由于 SSL/TLS 连接流程比较复杂,为了加深大家的印象,我会使用抓包工具对整个连接流程进行 抓包验证并且尽量多的用图片代替文字 来方便我们理解。
跟介绍 HTTP 时一样,我们同样的对我的播客主页 "https://blog.csdn.net/zhanggang740"进行访问。
当我在游览器中输入"https://blog.csdn.net/zhanggang740" 并按下回车后, SSL/TLS 连接到来时。
1. Client Hello
握手第一步是客户端向服务端发送 Client Hello 消息,这个消息里包含了一个客户端生成的随机数 Random1、客户端支持的加密套件(Support Cipher Suite)和 SSL Version 等信息。
抓包后的数据如下:
JackHttp -- HTTPS 为什么是安全的?
文章图片

从抓包数据中可以很明显的看到,客户端和 CSDN 服务器建立的 TLS 连接版本是 1.2 ,发送的 Random 值以及支持的加密套件(加密套件包含对称加密算法,非对称加密算法以及Hash算法)。
2. Server Hello
第二步是服务端向客户端发送 Server Hello 消息,这个消息会从 Client Hello 传过来的加密套件里确定一份加密套件,这个套件决定了后续加密和生成摘要时具体使用哪些算法,另外还会生成一份随机数 Random2。
注意,至此客户端和服务端都拥有了两个随机数(Random1+ Random2),这两个随机数会在后续生成对称秘钥时用到。
JackHttp -- HTTPS 为什么是安全的?
文章图片

这一步结束后,首次握手就结束了,客户端和服务端会存着如黄色部分数据:
JackHttp -- HTTPS 为什么是安全的?
文章图片

3. Certificate
这一步是服务端将自己的证书下发给客户端,让客户端验证自己的身份。具体包含服务端的网站证书,网站签发机构证书以及证书机构的签发根证书。
解释:发送的服务端的网站证书,网站签发机构证书以及证书机构的签发根证书分别包含如下具体信息:证书公钥信息、证书签名、证书签名算法、证书基本信息(主机、证书域名、注册名称、注册地址)等。
JackHttp -- HTTPS 为什么是安全的?
文章图片

红色部分就是我刚才说的证书中所包含的信息。绿色部分是什么呢?在我们游览器状态栏的左边有一个,我们点击打开看看
JackHttp -- HTTPS 为什么是安全的?
文章图片

JackHttp -- HTTPS 为什么是安全的?
文章图片

我们点开证书的明细,你会发现里面公开的证书签名、证书签名算法、证书基本信息和我们抓包获取的数据都是一致的。
4. Server Hello Done
Server Hello Done 通知客户端 Server Hello 过程结束。
JackHttp -- HTTPS 为什么是安全的?
文章图片

到这里服务器证书的打招呼流程就结束了。
总结一下:
JackHttp -- HTTPS 为什么是安全的?
文章图片

5. Client Verification Certificate (重点)
这一步发生在客户端本地,主要是验证服务器发过来的证书真实性,以此来确认服务器的身份。
证书验证过程由于包含加密相关的知识,如果你对加密不是很了解的话,推荐你看看上一篇
JackHttp – 浅谈编码、加密(对称加密,非对称加密,Hash算法)
1. 获取网站证书信息 根据服务端返回的 CSDN 证书信息,获取到证书签名,证书签名算法,证书基本信息。
2.证书机构认证网站证书 使用 证书机构的公钥 以及 证书机构公开的签名算法 对 CSDN网站证书签名进行验证得到 CSDN网站证书的原始数据证书基本信息,如果基本信息一致,则可以证明 CSDN 网站的证书确实是被 此认证机构签发的。因为验证的过后的证书,只有签发机构的秘钥才能签发,而秘钥只有签发机构有。
3.根证书认真证书机构 同样的验证方式,用根证书的公钥及签名算法来验证证书机构的证书是被根证书签发的。
到这一步我们就建立了根证书信任证书机构,证书机构信任网站证书的间接关系。也就是我们如果对根证书是信任的,间接的可以信任网站证书是真实性,对吧?,那么根证书是什么呢?
4.根证书的认证 所谓根证书,是CA认证中心与用户建立信任关系的基础,用户的数字证书必须有一个受信任的根证书。也就是说我们必须得无条件信任根证书,否则证书认证的流程就不成立了。那么根证书是什么呢?我们常见的根证书在系统安装时就会安装到我们操作系统里(无论是 Linux,Window,Mac OS,iOS,Androd 等等),几乎所有的操作系统,在安装的时候就会嵌入我们常用的根证书,只要操作系统没有被侵犯,是安全的,那么我们就认为根证书是值得信赖的。间接的来构建对网站证书的信任。
我的是 Mac OS 系统,我们来找一下本例中签发CSDN 的根证书

明白了吧?这一步走完,我们对服务器的身份就完全信任了,因为同一个网站是不会被签发给不同的两个人或机构的。
6. Client Key Exchange
【JackHttp -- HTTPS 为什么是安全的?】对服务器信任后,我们客户端就需要开始计算具体用于通信的秘钥了。
客户端本地此时会再次生成一个随机数 Random3,并用刚才获取到的服务端公钥非对称加密 Random3 生成 Pre-Master Key。
为什么用服务端公钥加密呢?因为此时客户端已经信任的服务端,使用客户端的公钥加密只有服务器才有私钥解密,这样加密出来的数据发给服务器肯定是安全的。
Client Key Exchange 就是将这个 key 传给服务端,服务端再用自己的私钥解出这个 Pre-Master Key 得到客户端生成的 Random3。
至此,客户端和服务端都拥有 Random1 + Random2 + Random3,两边再根据同样的算法就可以生成一份秘钥,握手结束后的应用层数据都是使用这个秘钥进行对称加密。
为什么要使用三个随机数呢?这是因为 SSL/TLS 握手过程的数据都是明文传输的,并且多个随机数种子来生成秘钥不容易被暴力破解出来。
为什么需要两边自己根据 Random1 + Random2 + Random3 算出秘钥呢?
主要原因:加密是需要损失性能的,所以 HTTPS 设计成用非对称加密来传输 Random,然后各自本地自己算出秘钥用户后面对称加密来传输具体的数据,达到性能的平衡,同事避免的秘钥再网络中传输
客户端将 Pre-Master Key 传给服务端的过程如下图所示:
JackHttp -- HTTPS 为什么是安全的?
文章图片

特别注意:Client Key Exchange 的加密信息发送出去后,客户端和服务器端本地会分别根据 Pre-Master Key 计算出 Master Key,这个算法世界上所有的计算机都是一致的。
其中 Master Key 包含:
1.客户端私钥 – 客户端发送数据给服务器时使用
2.服务器私钥 – 服务器发送数据给客户端时使用
3.客户端 HMAC 私钥 – 用于步骤 8 客户端与服务器加密握手时第一次加密验证使用
4.服务器 HMAC 私钥 – 用于步骤 10 服务端与客户端加密握手时第一次加密验证使用
7. Change Cipher Spec(Client)
这一步是客户端通知服务端后面再发送的消息都会使用前面协商出来的秘钥加密了,是一条事件消息。
JackHttp -- HTTPS 为什么是安全的?
文章图片

8. Encrypted Handshake Message(Client)
这一步对应的是 Client Finish 消息,客户端将前面的握手消息生成摘要再用步骤 6 协商好的Master Key 秘钥套件中取出 客户端HMAC秘钥 进行 HMAC 加密,这是客户端发出的第一条加密消息。服务端接收后会用相同的秘钥解密,能解出来说明前面协商出来的秘钥是一致的。
HMAC 也是 Hash 算法的一种,他和普通的 MD5、SHA1、SHA256 相比最大的区别是可以用秘钥进行加密,既能保证数据的摘要(小),也能保证安全性。了解 HMAC
JackHttp -- HTTPS 为什么是安全的?
文章图片

9. Change Cipher Spec(Server)
这一步是服务端通知客户端后面再发送的消息都会使用加密,也是一条事件消息。
10. Encrypted Handshake Message(Server)
这一步对应的是 Server Finish 消息,服务端也会将握手消息生成摘要再用步骤 6 协商好的Master Key 中的 服务端 HMAC 秘钥进行 HMAC 加密,这是服务端发出的第一条加密消息。客户端接收后会用相同的服务端 HMAC 秘钥解密,能解出来说明协商的秘钥是一致的。
这一步之后,SSL/TLS 的连接流程建立完成,服务器也会建立对客户端的信任。再这之后所有的数据都会使用步骤 6 算出来的服务端秘钥和客户端秘钥对数据进行对称加密,数据到达对方后再通过对应的秘钥进行解密,得到原数据。
11. Application Data
这一步就是具体的发送加密数据了,抓包后的数据我们是看不懂的。
JackHttp -- HTTPS 为什么是安全的?
文章图片

12 连接流程总结
JackHttp -- HTTPS 为什么是安全的?
文章图片

HTTPS 为什么是安全的
如果你完全掌握了 SSL/TLS 的连接流程,这个问题是不是已经不算是问题了?
因为在 HTTPS 的安全层 SSL/TLS 连接过程中服务器和客户端会对双方的身份进行认证,并且使得 HTTP 传输的消息在传输到 TCP 之前得到加密,之后数据再经过中间代理服务器、路由器、wifi热点、通信服务运营商等物理节点时,他们看到的将是加密后的数据,看不懂,另外由于身份验证、加密使得窃听和篡改的风险也将不存在。
分析 HTTPS 真的一定安全吗?
我们本文分析到了,在证书验证的过程中,其实是需要对根证书无条件信任的,并且根证书是对他签发的机构也是无条件信任的。那么在这个过程中,我们假设一下,某根证书签发的机构,他某一天万一变成坏人了,它在给某个坏人网站颁发一个证书,我们同样会对它颁发的网站证书进行信任,这就是风险。例如历史上出现的 Wosign证书事件 。
另外我们在信任第三方时,是需要第三方对秘钥进行严格保密的,如果第三方的证书秘钥被窃取,也会导致 HTTPS 的安全漏洞出现。
所以 HTTPS 也不会达到所谓的一定安全,不过这也是正常的,目前没有什么技术能达到所谓的完全安全,信任 HTTPS 就像我们信任支付宝和微信一样。我们默认是相信支付宝和微信的,我们才会把钱存在他哪里。如果有一天,支付宝要成为坏人,我们也不要觉得惊讶 ^ . ^.

    推荐阅读