# HTTPS 协议
HTTPS(HyperText Transfer Protocol Secure),也称为 HTTP over SSL/TLS,即超文本传输安全协议,是一种在 HTTP 的基础上进行安全通信的传输协议。默认端口为 443。
由于 HTTP 明文传输的特点,在传输过程中很容易遭到中间人攻击,攻击者可以窃听和篡改数据,并且伪造身份发送虚假数据,导致接收端无法判断数据的真实性。
HTTPS 可以对访问的网站进行身份认证,并在传输过程中保证数据的机密性和完整性,从而防止中间人攻击。
HTTPS 在 HTTP 下层增加了 SSL/TSL 安全层,用于保证传输过程的安全性。
# SSL/TSL
SSL(Secure Sockets Layer,即安全套接字层),由网景公司于 1994 年发明。在 v3 版本由 IETF 于 1999 年改名为 TLS(Transport Layer Security,即传输层安全)。
TLS1.1 于 2006 年发布;TLS1.2 于 2008 年发布,是目前应用最广泛的版本;TLS1.3 于 2018 年发布,在安全和性能方面得到进一步强化。
TLS 由记录协议、握手协议、警告协议、变更密码规范协议和扩展协议等子协议组成,综合使用了对称加密、非对称加密、身份认证等密码学前沿技术。
TLS 在建立连接时需要选择一组合适的加密算法来实现安全通信,这些算法的组合称为加密套件。加密套件的格式为密钥交换算法 + 签名算法 + 对称加密算法 + 摘要算法。
# 加密算法
通常使用加密算法来实现机密性,通过密钥加密明文和解密密文。加密算法分为对称加密和非对称加密两种。
# 对称加密
对称加密指的是加密和解密使用同一密钥,密钥不对外公开。
常用的对称加密算法包括 AES(密钥长度为 128、192 或 256) 和 ChaCha20(密钥长度固定为 256)。
对称加密的分组模式可以使用固定长度的密钥加密任意长度的明文。常用的分组模式包括 AEAD 的 GCM、CCM 和 Poly1305。
对称加密算法虽然性能很好,但是存在密钥交换问题,也就是约定的密钥在传输过程中容易被黑客窃取。
# 非对称加密
非对称加密指的是加密和解密使用不同密钥。一把是公开使用的公钥,另一把是严格保密的私钥。公钥加密的数据只能用私钥解密;私钥加密的数据只能用公钥解密。
常用的非对称加密算法包括 RSA 和 ECC。
RSA 基于整数分解,使用两个超大素数的乘积来生成密钥,推荐长度为 2048 位。
ECC 基于椭圆曲线离散对数。子算法 ECDHE 用于密钥交换,每次握手都会生成一对临时的公钥和私钥;ECDSA 用于数字签名。目前常用的曲线包括 P-256 和 x25519。
非对称加密虽然解决了密钥交换问题,但存在性能问题。
# 混合加密
混合加密结合了对称加密和非对称加密的优点,既能高效的加密解密,又能安全的交换密钥。
刚开始通信阶段,客户端使用非对称加密,然后用随机数生成对称加密算法使用的会话密钥,再用公钥加密;服务端拿到密文后用私钥解密,然后取出会话密钥。这样两端都实现了对称密钥安全交换,后面传输数据阶段使用对称加密。
# 摘要算法
摘要算法用于实现完整性。摘要算法使用哈希算法将任意长度的数据压缩映射成固定长度且独一无二的摘要字符串,相当于为数据生成一个数字指纹。数据有任何微小的改动生成的摘要字符串都会产生巨大的变化。
常用的摘要算法包括 MD5、SHA-1 和 SHA-2(SHA224、SHA256 和 SHA384),前两个算法由于安全性比较低,已经被 TLS 禁用。
完整性必须建立在机密性之上。发送方使用会话密钥加密原文和摘要字符串,接收方使用会话密钥解密后使用相同的摘要算法计算摘要字符串,将发送方的摘要字符串与自己计算的摘要字符串对比,如果相同则说明数据没有被篡改。
# 数字签名与证书
数字签名和数字证书用于实现身份认证,防止黑客伪造伪造身份。
# 数字签名
数字签名的原理是发送方使用私钥加密原文摘要,接收方使用公钥解密,然后比对计算出来的与解密出来的摘要字符串是否相同。
# 数字证书和 CA
为了解决公钥信任问题,需要引入高度可信的机构(也就是 CA),让他们签发认证的数字证书。证书内包括公钥、颁发对象、颁发者、有效期和序列号等,还包含一个 CA 生成的数字签名,它使用 CA 自己的私钥加密原文的摘要。
为了证明 CA 的自己身份,需要顺着证书链从二级 CA,再到一级 CA,最后到 Root CA 层层验证。Root CA 在信任链的最顶端,只能自己给自己背书。
# HTTPS 的工作原理
以下是当前主流的 ECDHE 握手过程。
- Client Hello
客户端会发送一个 Client Hello 消息给服务端,该消息中包含 TLS 版本、加密套件列表和一个用于协商生成会话密钥的随机数(Client Random)。
- Server Hello
服务端收到 Client Hello 消息后,会返回一个 Server Hello 消息。该消息中包含 TLS 版本、选择使用的加密套件和一个随机数(Server Random),
- Server Certificate
服务端为了证明自己的身份,需要将证书发送给客户端验证。
- Server Key Exchange
因为服务端选择了 ECDHE 算法,所以会发送 “Server Key Exchange” 消息。该消息包含椭圆曲线公钥(Server Params)和自己的私钥签名认证。
- Server Hello Done
服务端第一轮消息发送完毕后会发送该消息。客户端接收到该消息后开始顺着证书链逐级验证证书和签名的真实性。
- Client Certificate
在一些对安全要求高的场景,需要使用双向认证。那么客户端需要将证书发送给服务端认证。服务端收到该消息后也会逐层验证证书和签名的真实性。
- Client Key Exchange
客户端也生成了一个椭圆曲线公钥(Client Params)发送给服务端。
该阶段客户端和服务端都拿到了 Client Params 和 Server Params 两个密钥交换参数,然后使用 ECDHE 算法计算出随机数 Pre-Master。
客户端和服务端将 Client Random、Server Random 和 Pre-Master 三个随机数使用伪随机函数生成加密会话的主密钥 Master Secret,并通过主密钥派生出两端的会话密钥。
- Change Cipher Spec
有了会话密钥,客户端发送 Change Cipher Spec 消息表示以后改用对称算法加密通信。
- Finished
客户端把之前的所有数据通过摘要算法生成摘要字符串并对其加密,让服务端验证。
- Change Cipher Spec
服务端也会发送 Change Cipher Spec 消息表示以后改用对称算法加密通信。
- Finished
服务端把之前的所有数据通过摘要算法生成摘要字符串并对其加密,让客户端验证。
双方验证加密解密没问题后握手正式结束,后面收发的消息都会使用对称加密传输。