老青菜

TLS1.2 PreMasterSecret And MasterSecret

2019-06-12

在SSL/TLS中,Pre Master Secret(预主密钥)作用至关重要,无论是RSA加密算法、DH密钥交换算法,最终都是为了交换或者协商出Pre Master Secret。通过Pre Master Secret,结合其他参数,计算出Master Secret,作为整个会话的密钥。

Pre Master Secret

不同的密钥协商算法,计算Pre Master Secret(预主密钥)过程也不一样。那么我们来看下RSA交换算法、DH协商算法(ECDH、DHE、ECDHE)是如何得出Pre Master Secret的。

RSA

最常用的非对称加密算法,有以下两个特点:私钥加密,公钥解密;公钥加密,私钥解密。使用RSA算法交换密钥的流程如下:

  1. Client请求Server,Server返回证书,包含公钥Cer。
  2. Client生成随机数作为预主密钥S,使用公钥Cer加密,得到密文S1,发送给Server。
  3. Server收到密文S1,使用私钥解密,得到预主密钥S。

很明显,除非中间人攻击或者拿到私钥,第三方是无法窃取到会话预主密钥的,也就无法解密和窜改会话的。但是RSA存在向前攻击的问题,如果私钥泄漏了,以前劫持的会话记录都可以被解析。

如何生成

那么在SSL/TLS中,使用RSA交换算法,Pre Master Secret的是如何生成的呢?RFC2546中有以下描述:

struct {
   select (KeyExchangeAlgorithm) {
       case rsa:
           EncryptedPreMasterSecret;
       case dhe_dss:
       case dhe_rsa:
       case dh_dss:
       case dh_rsa:
       case dh_anon:
           ClientDiffieHellmanPublic;
   } exchange_keys;
} ClientKeyExchange;

struct {
  ProtocolVersion client_version;
  opaque random[46];
} PreMasterSecret;

client_version
 The latest (newest) version supported by the client.  This is
 used to detect version rollback attacks.

random
 46 securely-generated random bytes.

struct {
  public-key-encrypted PreMasterSecret pre_master_secret;
} EncryptedPreMasterSecret;

也就是针对RSA密钥交换算法,在ClientKeyExchange消息中,Client随机生成46字节+2字节的client_version,作为pre master secret。通过RSA公钥加密,传递给Server,Server只需要用私钥解密即可。

DH

Diffie Hellman,密钥协商算法,原理可以参考DH算法原理这篇文章,这里简单介绍一下协商流程:

  1. 定义素数g、p(只有1和自身的因数)
    g和p双方都知道,这里假如g = 7, p = 5,实际上这两个值都是很大的。
  2. 双方计算大数 P = g^X mod p
    Server生成随机数X2,假设X2 = 5,P2 = 7^5 mod 5 = 2。
    Client生成随机数X1,假设X1 = 2,P1 = 7^2 mod 5 = 4,
  3. 交换P1 P2
    Client有p、g、X1、P2,Server有p、g、X2、P1。
  4. 计算密钥S
    利用S = g^X mod p 计算密钥,对应Client,S1 = P2^X1 mod p = 4,
    对应Server,S2 = P1^X2 mod p = 4,S1=S2恒成立。

很显然,除非中间人攻击,即便知道g、p,窃取到A1、A2,也很那倒推出来A1、A2,也就没法计算出最后密钥。

ECDH

Elliptic Curve Diffie-Hellman Exchange,椭圆曲线密钥协商算法,是ECC和DH算法的结合。

  1. 和DH原理类似,把幂运算、取模运算替换成了点乘运算,速度更快,逆向分解难度更大。
  2. 和DH一样,证书公钥、私钥参与协商,对于Client,证书公钥作为随机数X1。对于Server,证书私钥作为随机数X2,存在向前攻击问题。

具体可以看这篇文章DH算法原理。另外openssl中已经移除了ECDH的支持。

DHE ECDHE

Elliptic Curve Diffie-Hellman Exchange Ephemeral,短暂的(椭圆曲线)密钥协商算法。多了一个Ephemeral(短暂的),即密钥是短暂的,每次握手都会协商出一个预主密钥,和RSA、DH、ECDH不同:

  1. RSA,证书公钥、私钥直接参与密钥交换,私钥泄漏,存在向前攻击问题。
  2. DH、ECDH,证书公钥、私钥参与协商,对于Client,证书公钥作为随机数X1。对于Server,证书私钥作为随机数X2。
  3. DHE、ECDHE,证书公钥、私钥不参与协商,每次握手都会计算随机数X。

很显然,这几种协商算法中,ECDHE是最安全的,即便当前会话的密钥泄漏了,也不影响之前的会话,是前向安全的。所以现在基本都是使用ECDHE算法。

如何生成

那么在SSL/TLS中,使用(EC)DHE算法,Pre Master Secret的又是如何生成的呢?RFC2546中有以下描述:

struct {
   select (KeyExchangeAlgorithm) {
       case rsa:
           EncryptedPreMasterSecret;
       case dhe_dss:
       case dhe_rsa:
       case dh_dss:
       case dh_rsa:
       case dh_anon:
           ClientDiffieHellmanPublic;
   } exchange_keys;
} ClientKeyExchange;

struct {
   select (PublicValueEncoding) {
       case implicit: struct {};
       case explicit: opaque DH_Yc<1..2^16-1>;
   } dh_public;
} ClientDiffieHellmanPublic;

也就是针对(EC)DHE密钥交换算法,Client在ClientKeyExchange消息中,随机生成X1,使用椭圆曲线或者g^X1 mod p计算得到DH_Yc,传递给Server。

同理,Server在ServerKeyExchange消息中,随机生成X2,使用椭圆曲线或者g^X2 mod p计算得到DH_Ys,传递给Client。最终双方计算出密钥S = DH_Ys^X1 mod p = DH_Yc^X2 mod p,也就是pre master secret。

Master Secret

针对所有的密钥交换算法,最终都会使用相同的算法将pre master secret转换成master secret。一旦master secret生成,pre master secret也就应该删除了。RFC2546#8.1中有以下描述:

master_secret = PRF(pre_master_secret, "master secret",
                          ClientHello.random + ServerHello.random)
                          [0..47];

生成过程很简单,拿到pre master secret,结合Client随机数和Server随机数,调用PRF(pseudo-random function)伪随机函数,截取48位。最后得到48字节的master secret。

最后我们总结一下master secret的生成过程。

参考链接

DH算法原理
TLS1.2
TLS1.3
HandShake Protocol

Tags: HTTP
使用支付宝打赏
使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏

扫描二维码,分享此文章