GB/T 38636-2020: 传输层密码协议 (TLCP) 技术规范分析
Reference
- GB/T 38636-2020
- Go语言实现的传输层密码协议(TLCP GMSSL),TLCP协议遵循 GB/T 38636-2020 Information security technology Transport Layer Cryptography Protocol (TLCP)
GB/T 38636-2020: 传输层密码协议 (TLCP) 技术规范分析
1. 范围与目的
本标准定义了传输层密码协议 (Transport Layer Cryptography Protocol, TLCP),旨在为网络中两个对等实体间的通信提供机密性 (Confidentiality)、完整性 (Integrity) 和身份认证 (Authentication)。其核心是定义了一个记录层协议和一个握手协议族,并规定了其所依赖的密码学原语和密钥计算方法。
2. 核心密码学原语与函数
TLCP的安全性基石由一系列密码学算法和函数构成。
2.1 基础密码算法
- 非对称密码算法: 用于身份认证、数字签名和密钥交换,支持SM2、RSA和IBC (SM9) 体系。
- 分组密码算法: 用于数据加密,指定使用SM4算法。其工作模式必须为CBC (Cipher Block Chaining) 或GCM (Galois/Counter Mode)。
- 密码杂凑算法: 用于生成摘要以进行完整性校验和密钥派生,支持SM3和SHA-256。
2.2 伪随机函数族
协议的密钥派生过程依赖于一个伪随机函数 (PRF),该函数基于一个数据扩展函数P_hash构建。
P_hash 函数
$$ P\_hash(\text{secret, seed}) = \text{HMAC}(\text{secret, } A(1) \Vert \text{seed}) \Vert \text{HMAC}(\text{secret, } A(2) \Vert \text{seed}) \Vert \dots $$P_hash函数利用基于哈希的消息认证码 (HMAC) 将一个密钥 (secret) 和一个种子 (seed) 扩展为任意长度的输出。其定义如下:其中 $\Vert$ 表示比特串的连接,而函数 $A(i)$ 迭代地生成HMAC的输入:
$$ \begin{cases} A(0) = \text{seed} \\ A(i) = \text{HMAC}(\text{secret, } A(i-1)) \end{cases} $$伪随机函数 (PRF) PRF是
$$ \text{PRF}(\text{secret, label, seed}) = P\_hash(\text{secret, label} \Vert \text{seed}) $$P_hash的一个直接应用,通过引入一个ASCII字符串标签label来区分不同的应用场景。
3. 密钥体系与派生
TLCP建立了一个分层的密钥结构,从一个临时的预主密钥开始,最终派生出用于保护应用数据的工作密钥。
预主密钥 (
pre_master_secret): 通过非对称密码学方法在客户端和服务端之间协商的初始共享密钥素材。主密钥 (
$$ \text{master\_secret} = \text{PRF}(\text{pre\_master\_secret, "master secret", } C.random \Vert S.random)[0..47] $$master_secret): 一个48字节的定长密钥,是所有会话密钥的根源。它由pre_master_secret、客户端随机数 $C.random$ 和服务端随机数 $S.random$ 通过PRF计算得出。工作密钥 (
$$ \text{key\_block} = \text{PRF}(\text{master\_secret, "key expansion", } S.random \Vert C.random) $$Working Keys): 从master_secret中进一步派生而来,用于记录层的数据加密和完整性校验。派生过程首先生成一个足够长的密钥块key_block:随后,
key_block被依次分割,以生成客户端和服务器的写MAC密钥、写加密密钥和写初始化向量(IV)。
4. 记录层协议 (Record Layer Protocol)
记录层负责处理所有待传输的数据分片、压缩、加密和认证。
数据处理流程:
- 分片 (Fragmentation): 将上层数据流分割成不大于 $2^{14}$ 字节的数据块。
- 压缩 (Compression): 对分片后的数据应用协商好的压缩算法(可为
null)。 - 加密与认证 (Encryption & Authentication): 对压缩后的数据进行密码学保护。
密码学保护机制:
CBC模式: 首先计算消息认证码 (MAC),然后与明文数据和填充(Padding)一同进行加密。MAC的计算覆盖了序列号、类型、版本、长度和数据本身。
$$ \text{MAC} = \text{HMAC\_hash}(\text{MAC\_write\_secret, seq\_num} \Vert \text{TLSCompressed.type} \Vert \dots \Vert \text{TLSCompressed.fragment}) $$AEAD模式 (GCM): 使用认证加密模式,同时提供机密性和数据源认证。它将一部分元数据作为附加认证数据(AAD),这部分数据只被认证而不被加密。
$$ \text{additional\_data} = \text{seq\_num} \Vert \text{TLSCompressed.type} \Vert \text{TLSCompressed.version} \Vert \text{TLSCompressed.length} $$
5. 握手协议 (Handshake Protocol)
握手协议是TLCP的核心协商机制,用于建立会话的安全参数。
核心目标:
- 协商协议版本、密码套件、压缩方法。
- 认证服务器,并可选地认证客户端。
- 生成共享的
master_secret。
$$ \text{verify\_data} = \text{PRF}(\text{master\_secret, finished\_label, SM3}(\text{handshake\_messages}))[0..11] $$Finished消息:Finished消息是握手过程的最后一步,用于交叉验证整个握手过程的完整性和密钥协商的正确性。它包含一个12字节的verify_data字段,其内容是基于master_secret和所有历史握手消息的PRF输出。其中
finished_label对于客户端是"client finished",对于服务端是"server finished"。
6. 附录A: GCM 可鉴别加密模式详解
附录A提供了对GCM模式的规范性描述,它是TLCP支持的一种高效的AEAD算法。
6.1 GCM 数学基础
有限域 $GF(2^{128})$ 上的乘法: GCM的核心运算之一是在有限域 $GF(2^{128})$ 上的乘法,记为 $X \cdot Y$。该域的模多项式由常数 $R = 11100001 \Vert 0^{120}$ 隐式定义。
** $GHASH_H(X)$ 函数**: $GHASH$是一个基于有限域乘法的泛杂凑函数,用于计算认证标签。给定哈希子密钥 $H$ (通过 $H = CIPH_K(0^{128})$ 计算得到)和分组数据 $X_1, \dots, X_m$,其计算过程为:
$$ Y_i = (Y_{i-1} \oplus X_i) \cdot H \quad (\text{for } i=1, \dots, m, \text{ with } Y_0=0^{128}) $$其结果 $Y_m$ 等价于多项式求值:$X_1 \cdot H^m \oplus X_2 \cdot H^{m-1} \oplus \dots \oplus X_m \cdot H$。
$GCTR_K(ICB, X)$ 函数: $GCTR$是GCM中用于加密的计数器模式函数。它通过加密一系列递增的计数器块 ($CB_i$),并将结果与明文分组 ($X_i$) 异或来生成密文。
$$ CB_i = inc_{32}(CB_{i-1}), \quad Y_i = X_i \oplus CIPH_K(CB_i) $$
6.2 GCM 可鉴别加密 (GCM-AE) 算法流程
给定密钥 $K$, 初始向量 $IV$, 明文 $P$, 和附加认证数据 $A$, GCM加密过程如下:
计算哈希子密钥: $H = CIPH_K(0^{128})$。
计算初始计数器分组 $J_0$: 根据 $IV$ 的长度,若 $len(IV)=96$ 比特,则 $J_0 = IV \Vert 0^{31} \Vert 1$;否则 $J_0$ 由对 $IV$ 的 $GHASH$ 计算得出。
加密明文: $C = GCTR_K(inc_{32}(J_0), P)$。
计算认证标签 $T$: a. 构造GHASH输入: 将 $A$ 和 $C$ 分别填充至128比特的整数倍,然后与它们的64位长度表示串联,形成一个比特串 $S'$。
$$ S' = (A \Vert 0^v) \Vert (C \Vert 0^u) \Vert [len(A)]_{64} \Vert [len(C)]_{64} $$b. 计算GHASH: $S = GHASH_H(S')$。 c. 加密GHASH输出: $T = MSB_t(GCTR_K(J_0, S))$,其中 $t$ 是期望的标签长度。
输出: 返回密文 $C$ 和鉴别标签 $T$。
GCM的可鉴别解密过程是加密的逆运算,通过重新计算标签并与接收到的标签进行比较来验证密文和附加数据的完整性和真实性。