现代密码学 mmtls

mmtls——微信安全通信协议分析

背景

作为腾讯公司开发的一款即时通信软件,微信支持跨通信运营商、跨操作系统的信息交互。微信原有的安全通信协议基于登陆时派发的 SessionKey,但由于SessionKey 只在应用层保护了请求的数据部分,因此仍然存在通过请求包头部的用户id和请求业务id进行映射关联分析的风险。同时,原有的密码学协议和算法与最新成果有一定差距,安全性存在一定不足。

综上,微信需要一套能够加密保护客户端到服务器之间所有通信数据、对开发人员透明的安全通信协议,由此基于TLS1.3的mmtls诞生了。

目标

系统的安全性、可用性、性能等指标之间往往存在复杂的相互影响,因此mmtls协议需要有以下特点:

  • 安全性。协议需要保证通信数据不被窃听、篡改、重放和伪造。
  • 低延迟。由于该协议为即时通信提供安全服务,因此需要保证数据传输没有明显的延迟。
  • 可扩展性。为了提高灵活性和安全性,协议需要及时添加安全强度更高的组件,并禁用被攻破的组件
  • 可用性。微信用户多,业务繁重,因此需要考虑极端情况下的可用性,以确保通信

协议设计

微信使用TCP协议进行报文传输,分为长连接和短连接两种。前者在mmtls基础上使用私有协议,后者则是HTTP协议加上mmtlsmmtls在微信通信层次中介于应用层和网络连接层,类似于TLSHTTPTCP之间的位置,这样不会影响其他网络协议。

同样与TLS相似的,mmtls有三个子协议:Record协议、Handshake协议和Alert协议,其中Alert协议和Handshake协议是Record协议的上层协议,因此在Record协议包中有专门的一个字段,用来确定当前Record数据包上层协议是HandshakeAlert还是应用层协议。

Handshake协议

Handshake协议的主要任务是完成ClientServer的握手协商,让通信双方安全地获得一致的对称密钥,以进行后续的通信数据加密传输。

TLS1.3有两种1-RTT的密钥协商方式(1-RTT ECDHE1-RTT PSK)和4种0-RTT的密钥协商方式(0-RTT PSK0-RTT ECDH0-RTT PSK-ECDHE0-RTT ECDH-ECDHE),而基于TLS1.3的mmtls结合了微信网络连接特点,在保证安全性和性能的前提下,只保留了三种密钥协商方式(1-RTT ECDHE1-RTT PSK0-RTT PSK)——长连接在建立TCP连接后会发送一个数据包用于验证长连接的连通性(中间路由可能不支持私有协议),因此使用1-RTT ECDHE1-RTT PSK;短连接则使用0-PSK,以减少时延,提高用户体验。

1-RTT

ECDHE

ECDH密钥交换协议包含两个过程——密钥生成与密钥协商。通信双方分别生成一对公私钥,并交换公钥;之后通过收到的公钥和自己的私钥计算出共享密钥,以对明文进行对称加密,实现加密通信。但这个过程存在中间人攻击的风险,即通信双方实际上是与攻击者分别协商出共享密钥,但却以为自己是和通信目标进行了协商。

以上问题的产生是由于通信双方无法确定报文是否来自目的端,因此在密钥协商过程中需要加入身份的认证:基于MAC的对称认证和基于数字签名的非对称认证。mmtls协议采用了后一种被称为ECDSA的算法,通信双方进行密钥协商时,分别签名公钥,收到消息后首先验证签名,签名无误才进行下一步的密钥协商。

具体过程如下:

  • 客户端发送client_pub_key
  • 服务器生成server_pub_keyserver_pri_key
  • 服务器用sign_keyserver_pub_key签名
  • 签名和server_pub_key发还客户端
  • 客户端用内置的verify_key验证验证签名

由于只用一方的签名即可抵抗中间人攻击,因此mmtls只对Server进行认证,不考虑Client的完整性。

PSK

PSKECDH握手中Server通过安全信道下发的内容,其中包含对称密钥keykey的密文ticket{key}

在协商时,Clientticket{key}发给Server,由于只有Server能够解密,因此Server用解密后的key计算协商数据的MAC完成认证。以上过程使用的都是对称算法,因此性能要优于ECDH

0-RTT PSK

1-RTT PSK握手之前,Client已经得到了一个对称加密密钥,因此可以直接用这个密钥加密数据,和ticket{key}一起发送给Server,因此节约了一个轮次。

更多的细节

  1. 0-RTT PSK的前向保密性。由于加密数据的安全性依赖于长期保存的密钥ticket,因此如果ticket泄露,基于ticket保护的所有数据都将失去保密性,因此可以在0-RTT PSK协商过程中同时完成ECDHE密钥协商,即0-RTT PSK-ECDHE
  2. Verify_key的下发问题。在1-RTT ECDHE中,Verify_key用于客户端验证签名,类似与RSA签名验证中公钥的作用,因此此密钥的下发问题就类似于公钥的派发问题。TLS采用证书链派发公钥证书,但为了减少额外的时间和带宽等资源消耗,且微信客户端是腾讯发布的程序,因此将Verify_key内置于客户端。
  3. sign_key泄露问题。如果Serversign_key泄露,则任何攻击者都可伪装为Server,因此需要及时地更新Verify_key,也就是及时撤销公钥。TLS通过CRLOCSP撤销公钥,但均存在延迟问题,微信通信的安全性无法获得保障。同样的,由于Verify_key内置于客户端,必要时其实可以通过强制升级客户端的方式完成Verify_key的更新。

Record协议

经过握手,通信双方获得了一致的对称密钥。TLS1.3 只能使用集成加密和消息认证码的算法进行加密。因此基于 TLS1.3 的mmtls选择AES-GCM作为认证加密算法——AES进行加密,采用Counter模式计算GMAC进行认证。

密钥扩展

由于 TLS1.3 要求通信双方不能采用完全一致的对称密钥,因此通过握手获得的密钥必须使用密码扩展组件HKDF进行扩展变换,获得对称加密参数:

  • Client Write MAC Key
  • Server Write MAC Key
  • Client Write Encryption Key
  • Server Write Encryption Key
  • Client Write IV
  • Server Write IV
参数的计算

通过握手获得的密钥,根据握手过程的不同分为两种:Static Secret(SS)Ephemeral Secret(ES)

1
2
3
4
5
6
7
//1-RTT ECDHE
ES = SS = ECDH_Compute_Key(server_pub_key, client_pri_key);
//0-RTT/1-RTT PSK
ES = SS = preshared_key;
//0-RTT PSK-ECDHE
SS = preshared_key,
ES = ECDH_Compute_Key(server_pub_key, client_pri_key);

扩展组件HKDF定义了两个函数——HKDF-Extract(salt, initial-keying-material)HKDF-Expand(pseudorandom key, info, out_key_length)——以保证扩展结果具有伪随机性。前者保证熵足够均匀,足够伪随机,后者实现密钥扩展,其中参数pseudorandom key一般是HKDF-Extract的返回值,参数info包括了握手消息的哈希、表示密钥用途的字符串常量和扩展结果长度。

扩展结果

因为使用AES-GCM作为认证加密算法,所以经过密钥扩展,mmtls最终获得四个参数,得到长度为2*encrypt_key_length + 2*iv_length长度的数据:

1
2
3
4
client_write_key = key_block[0...encrypt_key_length-1]
client_write_key = key_block[encrypt_key_length...2*encrypt_key_length-1]
client_write_IV = key_block[2*encrypt_key_length...2*encrypt_key_length+iv_length-1]
server_write_IV = key_block[2*encrypt_key_length+iv_length...2*encrypt_key_length+2*iv_length-1]

抗重放

由于1-RTT握手方式的一个数据包不包含具体的数据,因此ClientServer共同决定序列号起点,之后对每一个数据包编号后认证加密,便可实现抗重放的功能。

对于0-RTT握手方式,mmtls提出基于ClientServer的时间序列抵抗重放攻击,即保证超过一段时间的重放包被Server处理,而该段时间内的重放包在logic层参与下进行处理。

总结

微信安全通信协议mmtls在 TLS1.3 的基础上实现,通过ECDH协商密钥,通过ECDHA验证签名,实现通信双方握手,之后HKDF组件进行密钥扩展,获得真正的对称密钥,认证加密算法AES-GCM对数据包进行处理,保证微信通信的安全、轻量和高性能。

参考资料

TLS协议分析与现代加密通信协议设计
微信交互协议和加密模式研究
微信mmtls协议归纳和演示
基于 TCP 上 mmtls 安全传输实现
AES-GCM