Secure Sockets Layer(SSL) 是网景(Netscape) 在 1995 年提出的一种安全加密协议, 包括 1.0, 2.0 和 3.0 三个版本.

Transport Layer Security(TLS) 是由 IETF 主导的, 对 SSL 的更新. TLS 的初始版本和 SSL 3.0 基本相同. TLS 1.2/1.3 是当前的主流版本, 1.3 相对 1.2 在安全和性能上都有明显的提高.

Encrypt, Digest and Sign

数据经过加密后(Encrypt), 仅拥有对应密钥的人, 经过解密后可以看到数据的内容. 密钥的形式分为对称密钥和非对称密钥, 非对称密钥下, 常由第三方用公钥对数据进行加密, 随后仅私钥的持有者可以解密对应数据.

摘要(Digest)是指将不定长的数据映射到固定长度, 如 MD5 就会产生 128 比特的字符串. 数据发布者主动公布摘要后, 数据使用者可以按相同规则计算数据的摘要, 通过比对, 校验数据的完整性, 避免使用的数据被篡改.

签名(Sign)是指使用非对称密钥中的私钥计算数据对应签名, 使用者可以使用对应公钥验证数据和签名的关联性, 进而确保数据是由公钥对应方发布或认证的.

TLS 1.2

基于 RSA 交换密钥的 TLS 握手流程如下, 常见于 TLS 1.2:

  • 客户端连接到服务端的端口, 并发送 ClientHello, 主要包括: 支持的 TLS 版本, 支持的加密套件(cipher suite) 和 32 个字节的客户端随机数.
  • 服务根据收到的信息, 返回 ServerHello, 主要包括: 选择的 TLS 版本, 选择的加密套件和 32 个字节的服务端随机数; 以及服务端的 TLS 证书.
  • 客户端基于预先配置的可信 CA, 校验 TLS 证书中的主机名和预期相符.
  • 客户端生成 pre-master secret, 用收到证书中的公钥加密后发送给服务端, 即 ClientKeyExchange.
  • 服务端用私钥解密 ClientKeyExchange, 获的 pre-master secret, 配合前文的客户端随机数, 服务端随机数生成会话密钥.
  • 客户端使用 pre-master secret, 客户端随机数, 服务端随机数生成会话密钥.
  • 服务端用会话密钥加密本次握手的数据, 发送给客户端供其确认会话密钥.
  • 客户端用会话密钥加密本次我所的数据, 发送给服务端供其确认会话密钥.

客户端确认服务端身份依赖于 Certificate Authority (CA), 即证书颁发机构. 其工作机制可以简单的理解为:

  • 存在一些总所周知的证书颁发机构, 如 DigiCert, Let’s Encrypt.
  • 服务端提供主机名向这些 CA 申请公私钥证书, 公钥证书中含有服务端对应主机名, 并由 CA 的私钥签名.
  • 操作系统预先内置了这些 CA 的公钥证书, 客户端在和服务端建立链接时使用预置的 CA 的公钥来验证服务端的证书是可信.

基于 RSA 的密钥交换中, 由客户端生成 pre-master secret 后, 使用服务端的公钥加密后传输给服务端. 理论上, 仅服务端使用严密保护的私钥可以解密这部分数据获取到 pre-master secret. 随后, 客户端和服务端用 pre-master secret, 客户端随机数和服务端随机数生成相同的密钥, 用于后续数据的对称加解密.

TLS 1.3 相较于 TLS 1.2 在安全性和握手效率上都要较大的提高, 具体可以参考 为什么要使用TLS 1.3?.

SNI

Server Name Indication (SNI) 是 TLS 的一个扩展, 允许客户端在 ClientHello 中指定想要连接的主机名. SNI 主要用于同一 IP 的服务器承载多个主机名的场景.

诸如 Istio 这样的 Mesh 方案, 会大量使用 SNI 来做路由.