TLS Handshake

Posted by boredream on June 8, 2021

Https简要流程:

  1. 先TCP握手建立连接
  2. 在TCP上再TLS/SSL握手建立加密通道
  3. 最后在TLS/SSL通道上传输加密Http应用数据。

这里重点研究TLS(基于1.2版本)的握手部分。
TCP握手见之前文章,一些基本概念如对称加密、非对称加密、基础网络知识等文中略。

参考资料:
TLS WIKI
TLS1.2 RFC

TLS握手简略流程

  1. 互相hello。确定算法,交换随机数
  2. 交换参数用以协商 pre_master_secret(RSA、DHE)
  3. 交换证书,互相验证(通常只验证服务端的,去CA机构验证)
  4. 双方根据互换的随机数和pre_master_secret,生成相同的对称加密秘钥
  5. 互相确认已经切换到加密通话模式,且握手期间信息未被篡改

TLS握手详细流程

以访问 https://www.zhihu.com 为例,C=Client,S=Server

  1. C ClientHello:支持tls最高版本,随机数1,可用加密列表,期望session ID(可空)
  2. S ServerHello:选择共同支持tls最高版本,随机数2,从可用表中选择加密算法,确定session ID(新建or复用)
  3. S Certificate 证书:证书链(主到根),证书公钥subjectPublicKey,证书签名encrypted
  4. S ServerKeyExchange 交换秘钥(ECDHE):椭圆曲线,公钥pubkey,签名
  5. S ServerHelloDone 服务端Hello流程结束。
  6. C ClientKeyExchange 交换秘钥:公钥pubkey
  7. C ChangeCipherSpec 告知后续使用加密沟通
  8. C EncryptedHandshakeMessage 将整个握手期间的信息摘要加密后发给对方,以确认双方秘钥匹配,同时保证期间数据未被篡改
  9. S ChangeCipherSpec 同上
  10. S EncryptedHandshakeMessage 同上

秘钥协商流程详细介绍

对称秘钥的协商是TLS握手中的重点,可以有不同方案,以我们访问知乎为例。在ServerHello时,服务端选择了:
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

  • 对称秘钥协商:ECDHE
  • 证书验证:RSA
  • 对称加密:AES_128_GCM
  • 摘要:SHA256

对称秘钥协商以前会用RSA,但RSA不具有前向安全性,现在TLS1.2大部分都使用ECDHE。

不同协商方案

  1. RSA
    1. S ServerKeyExchange:无此步骤
    2. C ClientKeyExchange:生成PreMaster,用服务端证书里公钥加密后发送
    3. S 收到加密PreMaster,用对应秘钥解密
    4. 双方根据之前hello互传的俩随机数和PreMaster生成相同的秘钥用于对称加密
  2. DHE
    1. S ServerKeyExchange:发送公共数p和g,然后用私密数key1计算 g^key1 mod p 放在 pubkey里发给客户端
    2. C ClientKeyExchange:用服务端发来的p和g,以及自己的私密数key2计算,g^key2 mod p 放在pubkey发给服务端
    3. 双方根据对方的pubkey^key1/2 mod p 计算出同样的 PreMaster,再连同随机数一起生成对称加密秘钥
  3. ECDHE 基于DHE,使用椭圆曲线数学法替代mod计算
    1. S ServerKeyExchange:指定椭圆曲线;服务器本地计算个大数key1 乘以曲线的base point 得到新的point,作为pubkey
    2. C ClientKeyExchange:使用同样曲线,同理客户端本地计算个key2生成pubkey
    3. 双方根据对方的pubkey再结合自己的key利用曲线计算得到同样的 PreMaster,再连同随机数一起生成对称加密秘钥

协商方案对比

  1. DHE和ECDHE对比:
    1. 都是基于DHE,流程基本相同,都是协商秘钥算法。但具体算法不同,一个是基于mod一个是基于椭圆曲线。
  2. DHE(ECDHE)和RSA对比:
    1. RSA的对称加密秘钥发送是单向的C->S,无ServerKeyExchange步骤。而DHE需要互换pubkey所以需要双向KeyExchange。
    2. RSA不需要签名,本身PreMaster就是用公钥加密的,C->S中途如果有篡改,服务端的秘钥解析会出错。而DHE中有S->C时中途被篡改p,g的可能,因此在ServerKeyExchange里会携带一个数字签名,客户端收到后验证是否被篡改。ClientKeyExchange 时无需签名,因为只会传递pubkey,拦截了也无法知晓各自的私密数字。
    3. RSA不具备前向安全性,秘钥丢失后攻击者可以解密旧的会话信息。DHE具备前向安全性。
  3. DH和DHE对比:
    1. 普通DH协议是不具有前向安全性的,它会在证书中携带公共数字(因此不需要ServerKeyExchange步骤),服务端自己持有对应私密数字,这一对是固定的,如果丢失私密数字依然会暴露旧的会话信息。
    2. DHE(E=ephemeral短暂)具有前向安全性。它不在证书中携带DH参数,由服务端在每次会话中生成新的,这样即使攻击者拿到RSA证书的秘钥去反推得到某次会话的公共数,但也无法知晓那次会话双方的私密数,也就无法计算对称秘钥,因此是前向安全的。

DH原理简述

RSA 是一种非对称加密算法,此处略过不做详细介绍。
Diffie-Hellman 是一种秘钥协商的算法(不是加密算法),详细可以参考 Diffie-Hellman WIKI

大概原理可以参考上图

  1. 双方有个共享色(黄),然后各自持有一份私密颜色(A橘红色,B绿色)
  2. 双方把自己的私密颜色和共享色混合(A土黄色,B蓝色)后再互传
  3. 双方把对方发过来的混合色和自己的私密颜色再次混合,得到相同的颜色(双方都是:公共黄色+A私密颜色橘红色+B私密颜色绿色=棕色),最后以棕色作为对称秘钥加密信息互通

双方颜色的累加都一样,所以最后是同样的颜色,但混合的颜色互传时别人是无法反推私密颜色的。在DHE实际算法中,mod或椭圆曲线法都可以类比Hash、MD5等离散算法(只是便于理解,DHE实际上更特殊),你拿到结果但是无法反推源数据,就像混合色无法反推私密色,达到安全目的。

Wireshark 抓包

以访问 https://www.zhihu.com 为例

总体流程
TLS1

Client Hello TLS2

Server Hello TLS3

Server Certificate
TLS4

Server Key Exchange TLS5

Client Key Exchange
TLS6

其它简单的步骤图略

问题链‰

  1. 为什么要Https?
    Http不安全,会被监听、篡改、钓鱼冒充

  2. 如何防止监听?
    用对称加密算法,发送端秘钥加密,接收端同一个秘钥解密

  3. 如何交换对称加密秘钥?
    方法一:RSA非对称加密,客户端用服务端给的公钥加密「对称秘钥」发给对方,服务端用对应秘钥解密获取
    方法二:Diffie-Hellman 秘钥协商

  4. RSA如何确定公钥是否正确?
    去CA验证

  5. 如何确定数据是否被中途篡改?
    服务端返回数据携带数字签名,签名是将报文信息计算摘要后再用私钥加密。接收端将报文计算摘要,再用对应公钥解密签名对比摘要是否相同,以此验证完整性

  6. 签名验证的公钥如何确定是否正确?
    去CA验证(由此可见RSA作为一种对称加密算法,即可以传输秘钥用,也可以验证数字证书用)

  7. 和CA认证也是一次网络请求,如何保证安全?
    主机系统预装CA机构公钥,不走网络获取公钥,保证安全

  8. 为什么TLS交换对称秘钥使用DHE而非RSA?
    DHE具有前向安全性,RSA不具备。