HTTPS 相对于 HTTP 来说最重要的一点改变就是增加了传输加密的功能,避免了数据在网络上的明文传输。HTTPS 能做到这一点依赖于 SSL/TLS 的工作,SSL 是基于 HTTPS 下的一个协议加密层。
SSL(Secure Socket Layer)安全套接层,是1994年由Netscape公司设计的一套协议,并与1995年发布了3.0版本。
TLS(Transport Layer Security)传输层安全是 IETF 在 SSL3.0 基础上设计的协议,实际上相当于SSL的后续版本。 在实际使用的时候这两者的命名是有点混淆的,所以知道这两者的关系就 OK 了,本文后面统一用 SSL 了。
从具体架构层级上来看 HTTPS 是对 HTTP 的拓展,在 TCP 层之上,增加了 SSL/TLS 加密层。
HTTPS 建立连接传输数据的大概流程是:客户端通过服务端的公钥加密本地生成的一个随机数(也可以简单认为就是后续传输过程对称加密用到的 KEY),然后将加密结果发给服务端,服务端根据对应私钥去解密这个加密后的结果,拿到随机数,也就是对称加密的密钥之后,双方根据这个密钥开始进行对称加密的数据传输。
那 SSL/TLS 这一层来保证传输的安全性呢?这是本文想要聊的话题。
# SSL/TLS 存在的意义
我觉得最主要的目的就是为了安全的让客户端和服务器交换后续传输用到的对称密钥。
# SSL/TLS 握手概念
其实有点类似 TCP 的三次握手一样,SSL/TLS 在传输数据的过程当中也会有握手的概念,握手的的目的本质上也是为了完成密钥的生成和安全交换。
# SSL/TLS 握手的流程
从网上找来一张图,我学习的时候就是通过看这张图来理解 HTTPS 的传输流程的,配合下面的文字说的很清楚。
具体文字版传输流程如下
客户端向服务器发起握手🤝请求,也就是 ‘client hello’ 消息,同时也包含如下消息
- 随机字符串(
client random
) - 客户端支持的加密算法
- 随机字符串(
服务器对握手请求进行相应,回应 ‘server hello’ 消息,也包含如下消息
- 随机字符串(
server random
) - 数字证书
- 服务器从客户端支持的加密算法列表里选择好的加密算法
数字证书包含的内容很多,除了公钥信息之外,还包含签发机构,域名,有效期等信息。
- 随机字符串(
客户端收到服务器的回应之后,开始对服务器返回的信息进行如下处理
- 校验证书有效性
- 继续生成随机数(
premaster secret
)并用服务器公钥加密
客户端将处理完成之后将公钥加密后的随机数
premaster secret
发给服务器。服务器使用私钥解密来获取客户端的随机数
premaster secret
这个随机数的交换是很重要的,它保证了中间人没办法看到真正的随机数内容。
此时客户端和服务端都有三个随机数,然后双方使用相同的加密算法来通过这三个随机数生成相同的密钥 master secret。这个 KEY 就是用作最终用来对称加密传输的密钥。
这步不涉及传输过程,是在双方本地完成的。
客户端和服务端互相发送就绪消息。内容是使用 KEY 加密后的 “finished” 信号
这步骤本质是在验证之前的流程是对的,同时保证后续传输是没问题的
双方认为建立安全链接,开始使用上面生成的 KEY 进行对称加密进行安全传输。
# 三个随机数的作用
上面的传输过程涉及到三个随机数: ① 客户端生成的 client random
② 服务端生成的 server random
③ 最后一步客户端生成的 premaster secret
。
这三个随机数最终的目的是生成 master Secret
,这个三个随机数都会在服务器和客户端之间记性传输,但是 最终的 master secret
是不会在两端传输的 ,而是通过一个约定好的算法生成。
premaster secret
和 client random
/server random
的区别在于:它的传输是用公钥加密的,而后两者是明文传输的。这样第三方是没有办法完整的拿到这三个随机数,也就没有办法生成 master Secret
。
# SSL/TLS 涉及到的一些概念
**数字证书。**数字证书本质是证书认证机构(CA)颁发的,一般包含以下内容:公钥、名称、颁发者、有效期、SHA-256指纹、签名算法,序列号(这是证书颁发机构为该证书分配的唯一标识符)。
**证书链 (certificate chain):**包含根证书、中间证书、用户证书,是组成一条完整证书的信任链。用于认证实体合法身份的证书列表,只有当整个证书信任链上的各个证书都有效时,浏览器才会认定当前颁发给用户的证书是有效和受信任的。
# SSL/TLS 设计到的实际应用场景
有的时候看到下面这种情况的时候,尽管是https链接方式,但还是报安全隐患,需要在浏览器的地址栏左侧查看一下证书的有效期是不是过了。
客户端开发过程中的证书锁定。默认情况下 App 种进行 TLS 传输的时候,系统会自动验证证书。不过有的时候为了防止抓包,在客户端本地内置证书或者公钥,这样在客户端验证服务端下发证书的过程中,就能判定和自己对话的到底是不是真的服务端,如果不是的话,证书就会校验失败,SSL 握手失败,最终中断传输,达到防止抓包的目的。参考之前 iOS 禁用抓包实践 (opens new window) 这篇文章。
参考地址: