YEGUO

HTTPS 原理

|
|
19 min read

https过程

​ 在TLS/SSL握手过程中,ClientHello 和 ServerHello 消息本身通常不加密,它们是明文传输的。这是因为在握手的初步阶段,双方还没有建立起加密通道,因此初始的握手消息需要在明文中传递。

1.客户端Hello: 客户端在握手开始时向服务器发送ClientHello消息,其中包含一个随机数(ClientRandom),以及其他一些握手参数。

2.服务器Hello: 服务器在接收到ClientHello后,向客户端发送ServerHello消息,其中包含另一个随机数(ServerRandom),以及选择的加密套件、协商的协议版本等信息。

ServerHello 阶段通常包含服务器的数字证书。数字证书中包含了服务器的公钥以及与之相关的信息,如证书颁发者、有效期等。这个数字证书是由服务器的证书链中的最顶层证书签发的,而这个最顶层的证书通常由一个受信任的证书颁发机构(CA,Certificate Authority)签发。

​ 客户端在收到 ServerHello 消息中的数字证书后,会验证证书的合法性,包括检查证书的签名是否有效、证书是否在有效期内、证书是否由受信任的CA签发等。验证通过后,客户端可以提取服务器的公钥,用于后续密钥协商和加密通信的建立。这个公钥通常用于协商会话密钥的加密

  1. CA验证: 客户端在收到服务器的证书后,需要验证服务器证书的有效性。这个验证过程包括以下几个步骤:
    • 证书链验证: 客户端需要检查服务器证书是否是由可信的CA签发的。客户端本地存储了一组信任的CA的根证书,用于验证服务器证书链的合法性。
    • 证书是否过期: 客户端检查服务器证书的有效期,确保它没有过期。
    • 域名匹配: 客户端检查服务器证书中的域名是否与实际连接的域名匹配。这是为了防止中间人攻击。
  2. 公钥提取: 如果服务器证书通过了验证,客户端就可以从服务器证书中提取服务器的公钥。
  3. 密钥交换: 客户端使用服务器的公钥来加密一个Pre-Master Secret并发送给服务器。服务器使用自己的私钥解密这个消息,得到Pre-Master Secret。

**3.生成Pre-Master Secret:**客户端使用这两个随机数以及其他一些握手参数,例如支持的加密算法、协商的协议版本等,生成一个共同的Pre-Master Secret。

4.Pre-Master Secret的安全传输: 客户端将生成的Pre-Master Secret通过服务器的公钥进行加密,然后发送给服务器。这一步使用了非对称加密,确保了Pre-Master Secret在传输过程中的安全性。

5.Master Secret的生成算法: 一旦服务器收到已加密的Pre-Master Secret并解密,客户端和服务器都使用以下算法计算Master Secret:

MasterSecret = PRF(PreMasterSecret, "master secret", ClientHello.random + ServerHello.random)
// "master secret"是PRF中的标识符,指示生成Master Secret。PRF 表示伪随机函数(Pseudo-Random Function)

6.Master Secret生成: 服务器收到已加密的Pre-Master Secret后,使用自己的私钥进行解密,获取Pre-Master Secret。然后,客户端和服务器都使用双方生成的随机数以及Pre-Master Secret计算出一个共同的Master Secret。

7.生成会话密钥: 通过Master Secret再次使用密钥派生函数(PRF 或 HKDF),生成最终用于对称加密通信的对称会话密钥。

伪随机函数密钥导出

​ 伪随机函数(Pseudo-Random Function,PRF)是一种能够生成近似于真随机函数的算法,其输出表现为随机性。在SSL/TLS握手过程中,PRF的主要作用是生成密钥材料,例如生成Master Secret。

在SSL/TLS中,PRF的具体实现取决于协议版本。在TLS 1.2及之前的版本中,PRF的定义如下:

PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR P_SHA-1(S2, label + seed)
  • secret 是Pre-Master Secret。
  • label 是一个字符串标识符,用于区分生成不同的密钥材料。
  • seed 是随机数。

​ P_MD5 和 P_SHA-1 是基于MD5和SHA-1散列函数的伪随机函数。S1和S2是通过拆分Pre-Master Secret而得到的两个半分。

​ 在TLS 1.2中,PRF的计算方式得到了改变,引入了更灵活的PRF(secret, label, seed) = P_hash(secret, label + seed),其中P_hash 是一个基于HMAC(Hash-based Message Authentication Code)的伪随机函数,可以使用不同的散列算法,如SHA-256或SHA-384。

​ TLS 1.3进一步简化了密钥交换的流程,使用了更现代的密码学原语,并且取消了显式的PRF。在TLS 1.3中,密钥的生成主要通过HKDF(HMAC-based Extract-and-Expand Key Derivation Function)实现。

​ TLS 1.3中的HKDF算法会使用双方生成的随机数。在握手过程中,客户端和服务器各自生成一个随机数,并在握手消息中交换这些随机数。这些随机数用于增加握手过程的熵,从而提高密钥的随机性。

​ 在HKDF的上下文中,这些随机数被作为输入之一,用于派生出最终的对称密钥。这样,不同的会话将有不同的随机数,导致生成不同的密钥,增强了密钥的唯一性和安全性。

​ TLS 1.3中使用的HKDF(HMAC-based Extract-and-Expand Key Derivation Function)算法是基于HMAC(Hash-based Message Authentication Code)的。HKDF包括两个步骤:Extract和Expand。

  1. Extract: 在这一步,将原始输入(包括双方生成的随机数)通过一个伪随机函数(PRF)与salt(如果提供的话)进行HMAC运算,生成一个伪随机密钥(PRK,Pseudo-Random Key)。

    公式表示为:PRK = HMAC-Hash(salt, input)

  2. Expand: 利用PRK和其他信息(比如上下文标签,长度等),通过多次调用伪随机函数派生出最终的对称密钥。

    公式表示为:OKM = HKDF-Expand(PRK, info, L)

    其中,OKM是输出密钥材料,HKDF-Expand是一个用于扩展密钥材料的函数,info包含了上下文标签和其他信息,L是输出密钥材料的长度。

​ 具体的哈希函数、PRF和其他参数的选择取决于协商时所选择的密码套件,HKDF是一个灵活的密钥派生方案,可以适应不同的密码学要求。

加密套件

​ 加密套件是TLS通信中用于协商加密算法、鉴别方法等参数的一组规范。在TLS握手过程中,客户端和服务器会协商选用一个加密套件,这个套件定义了一组加密算法、鉴别方法和其他相关参数。

TLS 1.3支持的一些加密套件包括:

  • TLS_AES_128_GCM_SHA256: 使用AES-128-GCM进行加密和认证,以及SHA-256进行鉴别。
  • TLS_AES_256_GCM_SHA384: 使用AES-256-GCM进行加密和认证,以及SHA-384进行鉴别。
  • TLS_CHACHA20_POLY1305_SHA256: 使用ChaCha20-Poly1305进行加密和认证,以及SHA-256进行鉴别。

​ 这些套件包括了对称加密算法、鉴别算法和其他相关参数的组合。具体选用哪个套件取决于客户端和服务器双方的支持和协商结果。

数字证书

​ 数字证书是一种用于在网络中进行安全通信的电子证明书。它用于验证与证书相关联的实体(通常是一个网站或服务)的身份。数字证书的主要组成部分包括:

  1. 主体信息(Subject): 证书中指定了证书所属实体的信息,如组织、组织单元、通用名(通常是域名)等。
  2. 公钥: 证书中包含了与该证书相关联实体的公钥。这个公钥用于加密通信或验证数字签名。
  3. 证书颁发者信息(Issuer): 证书的颁发者,即签发该证书的证书颁发机构(CA)。CA是一个受信任的第三方,用于证明证书中所含公钥确实属于证书中所指明的实体。
  4. 签名: 证书的数字签名是由颁发者使用其私钥生成的,用于验证证书的完整性和真实性。
  5. 有效期: 证书有一个有效期限,超过这个期限,证书将不再被认为是有效的。

​ 数字证书通过在通信中引入第三方(CA)的信任,提供了一种机制来确保通信的安全性和真实性。在HTTPS中,服务器通常会提供数字证书以证明其身份,同时客户端会验证证书的有效性。这样,双方可以协商出一个对称密钥,用于后续通信的加密。

数字签名

​ 数字签名是一种用于验证文档、消息或数据的完整性和来源真实性的技术。数字签名通过使用加密算法生成一个与特定数据相关联的数字代码(签名),并将其附加到原始数据上。这个数字签名可以被其他人用于验证数据的完整性和签名者的身份。

下面是数字签名的基本步骤:

  1. 生成消息摘要(Hash): 对原始数据应用哈希函数,生成一个固定长度的消息摘要(哈希值)。这个哈希值通常是一个唯一表示原始数据的字符串。
  2. 使用私钥加密摘要: 发送者使用其私钥对生成的消息摘要进行加密,形成数字签名。
  3. 附加数字签名: 数字签名被附加到原始数据上,形成签名的数据。
  4. 传输数据: 签名的数据和公钥一同传输给接收者。
  5. 验证签名: 接收者使用发送者的公钥解密数字签名,得到消息摘要。然后,接收者对接收到的原始数据应用哈希函数,生成一个新的消息摘要。
  6. 比较摘要: 接收者比较用私钥解密得到的消息摘要与重新计算的消息摘要。如果两者匹配,证明数据完整且签名者是可信的。

​ 数字签名的关键在于私钥只能由签名者持有,而公钥可以被分发给任何需要验证签名的人。这样,任何人都可以使用公钥验证数字签名,但只有持有相应私钥的实体才能生成有效的数字签名。

数字签名验证

数字签名验证通常涉及以下步骤:

  1. 获取公钥: 首先,需要获取签名者的公钥。在数字证书中,公钥通常包含在证书中,而证书本身可以通过一系列的信任链验证(通过 CA 或其他手段)获取。
  2. 获取消息摘要: 要验证数字签名,需要对原始数据进行哈希运算,得到消息的摘要。这个哈希值通常是通过安全的哈希算法(如SHA-256)生成的。
  3. 解码数字签名: 数字签名通常是二进制数据。需要使用签名者的公钥对数字签名进行解码,以获取原始的数字签名值。
  4. 验证签名: 将解码后的数字签名与消息摘要进行比较。如果它们一致,说明数字签名有效,消息未被篡改。

​ 如果在这个过程中的任何一步失败,或者签名不匹配,那么验证将失败,表示消息可能已经被篡改或签名者并非预期的实体。

​ 需要注意的是,数字签名的有效性与签名者的私钥和签名算法有关。只有持有相应私钥的实体才能生成有效的数字签名。

服务器获取数字证书

​ 服务器通常会从数字证书颁发机构(CA,Certificate Authority)处获得数字证书。下面是简要的过程:

  1. 证书请求生成: 服务器首先生成一个证书请求(CSR,Certificate Signing Request)。这包含了将包含在证书中的信息,如公钥、组织信息等。
  2. 私钥生成: 同时,服务器会生成一对密钥,包括公钥和私钥。私钥是秘密的,服务器会妥善保存它。
  3. CSR提交给CA: 服务器将生成的CSR提交给选择的CA。CSR中包含了服务器的公钥以及一些其他身份信息。
  4. CA验证: CA会对服务器提交的信息进行验证,确保服务器拥有CSR中提到的域的控制权。这个过程可能涉及到不同的验证方法,包括电子邮件验证、DNS记录添加等。
  5. 颁发证书: 一旦验证通过,CA将颁发数字证书,并在其中包含服务器的公钥。该证书还包含CA的数字签名,用于验证证书的真实性。
  6. 证书安装: 服务器收到数字证书后,将其安装在服务器上。同时,私钥也需要与证书一起保存。

​ 通常情况下,数字证书的有效期是有限的,因此在证书到期之前,服务器可能需要定期更新证书,通常是通过提交新的CSR给CA进行重新签发。

​ 需要注意的是,一些大型的CA可能会向企业出售数字证书,而其他一些CA可能会提供免费的证书服务。选择CA通常取决于用例的需求和信任级别。

​ 对于传统的服务器通信,服务器通常只需要一次性地获取证书,然后可以用该证书与多个客户端建立安全连接。证书是服务器身份的标识,用于证明服务器是可信的。一旦服务器获取了有效的数字证书,它就可以与多个客户端建立安全通信,而不需要为每个客户端单独申请证书。

​ 这是因为数字证书是为特定的域名(或IP地址)签发的,并不是为特定的客户端。当客户端与服务器建立连接时,它会验证服务器的数字证书是否有效,以确保与服务器通信的安全性。因此,服务器只需要在初始设置中获取并配置好证书,之后便可以与多个客户端进行通信。

© 2023 - 2026 YEGUO