0%

图解HTTP:HTTPS

HTTP的缺点

  • 通信使用明文(不加密),内容可能会被窃听。
  • 不验证通信的身份,因此有可能遭遇伪装。
  • 无法验证报文的完整性,所以有可能篡改。

未加密的协议都会出现类似的问题。

HTTPS = HTTP + 加密 + 认证 + 完整性保护

HTTPS 是身披 SSL 外壳的 HTTP。HTTPS 并非是应用层的一种新协议,只是 HTTP 通信接口部分用 SSL 和 TLS 协议代替而已。

原本HTTP直接和TCP通信;使用SSL时,先和SSL通信,再由SSL和TCP通信。

SSL是独立于HTTP协议的,应用层的其他协议也可以配合SSL协议实现网络安全。

相互交换密钥的公开密钥加密技术

SSL使用公开密钥加密的加密处理方式。公开密钥加密使用一对非对称的密钥——公钥、私钥。

公钥加密,私钥解密。客户端持有公钥,用私钥对发送的信息加密;服务器持有私钥,用私钥对客户端发送的密文解密。

非对称加密

注意:客户端的私钥是服务器事先传递过去的,即服务器先生成一对公钥私钥,把私钥发送到客户端,客户端才能用私钥进行加密。

在HTTPS中,对称加密与非对称加密混合使用。因为非对称加密适合加密小量数据,一般数据应使用对称加密进行加密解密。所以在HTTPS中,使用非对称加密的是对称密钥,即客户端把对称密钥用私钥加密发送到服务器,后续服务器用对称密钥加密解密一般的消息。

混合加密

确保服务端公钥安全

因为客户端需要用服务端的公钥进行加密,所以首先要确保客户端能拿到正确的服务端公钥。公钥在下发的时候会被替换劫持,这里通过第三方认证机(CA)构确认公钥的正确性。

认证的方式通过数字签名校验实现,简单来说就是CA私钥加密HASH(通过内容生成),公钥解密得出HASH,比对从收到的内容生成的HASH是否相等。

这个过程如下:

前提准备:

  • 客户端提前安装了CA的公钥。
  • 服务端获取CA颁发的证书。
    1. 服务端生成一对公钥、私钥,私钥自己存着,公钥最终要传给客户端。
    2. 把公钥登记到CA,CA对公钥内容做HASH,对HASH值用CA私钥加密,密文+公钥打包成证书发送给服务器。
客户端事先安装CA公钥
公钥转证书

校验流程:

  1. 服务端发送公钥证书给客户端;
  2. 客户端对证书中的密文用CA的公钥解密得出HASH,对证书中的公钥内做HASH,对比两个HASH值。正确则提取公钥存到客户端。
  3. 客户端使用服务端的公钥加密与服务器传输,开始加密通信。使用上述的混合加密方式,即非对称加密交换对称加密密钥,然后双方使用对称密钥进行加密通信。
提取服务端公钥

RSA公钥、私钥的作用助记

既然是加密,那肯定是不希望别人知道我的消息,所以只有我才能解密,所以可得出公钥负责加密,私钥负责解密;同理,既然是签名,那肯定是不希望有人冒充我发消息,只有我才能发布这个签名,所以可得出私钥负责签名,公钥负责验证

数字签名就是使用私钥对数据摘要进行签名,并附带和数据一起发送。可以起到防篡改、防伪装、防否认的作用。

证书则是由CA机构自己的私钥签发的数字签名。解决的签名的权威性问题,奠定了信任链的基础。

HTTPS安全通信过程

服务端已经生成公钥、私钥,并通过CA获得公钥证书。客户端已经事先安装CA公钥。

HTTPS过程

具体过程:

HTTPS过程_具体
  1. 客->服,Handshake: ClientHello
  • 客户端通过发送 Client Hello 报文开始 SSL 通信。
  • 报文中包含客户端支持的 SSL 的指定版本、加密组件(Clipher Suite)列表(所使用的加密算法及密钥长度等)。
  1. 服->客,Handshake: ServerHello
  • 服务器进行 SSL 通信,以 Server Hello 报文作为应答。
  • 和客户端一样,在报文中包含 SSL 版本以及加密组件。
  • 服务器的加密组件内容是从接收到的客户端加密组件内筛选出来的。
  1. 服->客,Handshake: Certificate
  • 服务器发送 Certificate 报文。报文中包含公钥证书。
  1. 服->客,Handshake: ServerHelloDone
  • 最后服务器发送 Server Hello Done 报文通知客户端,最初阶段的 SSL 握手协商部分结束。
  1. 客->服,Handshake: ClientKeyExchange
  • 第一次握手结束后,客户端以 Client Key Exchange 报文作为回应。
  • 报文中包含通信加密中使用的一种称为 Pre-master secret 的随机密码串,该密码已用步骤 3 的公钥进行加密。
  1. 客->服,ChangeCipherSpec
  • 客户端继续发送 Change Cipher Spec 报文。告诉服务器之后的通信将采用该密码进行加密。
  1. 客->服,Handshake: Finished
  • 客户端发送 Finished 报文。该报文包含链接至今全部报文的整体校验值。
  • 这次握手协商成功的标准是服务器能正确解密该报文。
  1. 服->客,ChangeClipherSpec
  2. 服->客,Handshake: Finished
  3. 客->服,Application Data(HTTP)
  • 客户端和服务端的 Finished 报文交换完毕后,SSL 连接建立完成。从此开始发送 HTTP 请求。
  1. 服->客,Application Data(HTTP)
  • 应用层协议通信,发送 HTTP 响应。
  1. 客->服,Alert: warning, close notify
  • 由客户端断开连接。

参考:HTTPS加密流程理解 - fengf233 - 博客园

单向认证与双向认证

上述的HTTPS基本流程就是单向认证,即指认证服务端的证书。单向认证中需要额外代码的情况往往是服务器下发的证书是CA颁发的,而是自签的,所以在检验服务端私钥证书时就要自定义的逻辑。

而双向认证,则是在ServerHelloDone前,发送来自客户端的公钥证书,服务端收到后用根证书解密客户端证书,取出客户端私钥。双向认证在确保了服务端的正确性,也确保了客户端的正确性。

两者过程对比:

单向认证:

  1. 客->服,发起HTTPS连接请求,把SSL协议版本发送给服务端。
  2. 服->客,发送服务端把本机公钥证书(server.crt)。
  3. 客,校验公钥证书(server.crt),取出服务端公钥。
  4. 客->服,并发送用服务端公钥加密的随机生成密钥R。
  5. 服,用私钥(server.key)解密得出密钥R。
  6. 服<->客,用密钥R进行加密通信。

双向认证:

  1. 同上(客->服,发起HTTPS连接请求,把SSL协议版本发送给服务端)。
  2. 同上(服->客,发送服务端把本机公钥证书(server.crt))。
  3. 同上(客,校验公钥证书(server.crt),取出服务端公钥)。
  4. 客->服,把自己的公钥证书(client.crt)发送给服务端。
  5. 服,用根证书(root.crt)解密客户端公钥证书,拿到客户端公钥。
  6. 客->服,发送自己支持的加密方案。
  7. 服->客,根据双端能力,选择双方都能接受的加密方案,使用客户端公钥加密后发送。
  8. 客->服,使用私钥解密加密方案,生成随机密钥R,使用服务端公钥加密后发送。
  9. 同上5(服,用私钥(server.key)解密得出密钥R)。
  10. 同上6(服<->客,用密钥R进行加密通信)。

参考:

SSL和TLS

SSL 先有,TSL 是以 SSL 为原型开发的协议,有时会统一称该协议为 SSL。

不推荐一直使用HTTPS

  • 与明文通信相比,加密通信会消耗更多的 CPU 及内存资源。所以敏感信息才使用 HTTPS 加密通信。
  • 证书的费用开销。

欢迎关注我的其它发布渠道