a house in the woods

Hi, nice to meet you.

https是在http的基础上加入tls对数据进行加密,增加安全度的协议。

tls所做的工作可以简单概括为,通过非对称加密的数据交换,双方生成相同的对称加密的密钥来对后面的数据进行加密解密。下面再稍微详细的说明其握手阶段的步骤。

tls会将所有信息封装,对信息进行分类。而握手信息也有它对应的类型为Handshake。而Handshake同时也是一种协议规范。在这种协议下也会对握手信息进行类型区分。握手过程涉及到的主要类型如下:

  1. Client Hello

它会携带以下这些信息:

  1. Random:
    1. 4字节的UTC信息
    2. 28字节的随机码
  2. Session ID:之前连接的会话ID,如果失效或者未连接过,则为空
  3. 客户端支持的加密方式列表
  4. server_name_extension:可简单认为是为了告诉服务器客户端需要哪个Host(域名)的证书

收到Client Hello后,服务器会回应三种信息:

  1. Server Hello
    1. Random,意义同Client Hello
    2. Session ID,意义同Client Hello
    3. 服务器在客户端支持的加密方式中,选择其同意使用的方式
  2. Certificate(证书)
  3. Server Hello Done:标志双方Hello阶段完成

客户端会:

  1. 验证证书的有效期
  2. 验证证书的颁发机构是否受信任(已在本机中内置),
  3. 利用该证书颁发机构的公钥对证书的签名进行解密(数字签名是私钥加密,公钥解密),再检查是否与证书的哈希一致(确认是否是该CA的颁发的)
  4. 确认证书中的域名是否正确

验证成功后,进行密钥交换。

  1. Client Key Exchange
    客户端将自己的经过随机数据padding后的pre-master secret(固定,保存在应用程序中),使用证书提供的public key加密后发送给服务器。

然后发一条Change Cipher Spec信息,表示之后的消息都将会按合意的方式加密。

此时客户端和服务器都有per-master secret, client randomserver random的信息,那么双方会根据这些信息生成相同的master secretPRFPseudo-Random Function,伪随机函数

1
master_secret = PRF(pre_master_secret, "master secret", ClientHello.random + ServerHello.random)

有了master secret以后,会使用它再衍生出4个key

1. client_write_MAC_secret 客户端为信息生成16字节的完整性校验码,服务端对信息解密后,按同样的方式生成校验码,判断是否与信息的后16字节是否一致
2. server_write_MAC_secret 服务为信息生成16字节的完整性校验码,客户端对信息解密后,按同样的方式生成校验码,判断是否与信息的后16字节是否一致
3. client_write_key 客户端加密数据,服务端解密来自客户端的数据
4. server_write_key 服务端解密数据,客户端解密来自服务端的数据
  1. Finished

客户端会发送所有之前的handshake messages,并对使用master secrethandshake messages生成验证数据来确认之前的密钥交换和验证步骤是否成功。

1
verify_data = PRF(master_secret, "client finished", MD5(handshake_messages) + SHA-1(handshake_messages))

当以上步骤都完成后,HTTP应用层的数据传输会用client_write_keyserver_write_key进行对称性的加密解密。

本文引用:

  1. The First Few Milliseconds of an HTTPS Connection
This article was last updated on days ago, and the information described in the article may have changed.