6. TLS 记录协议 (The TLS Record Protocol)
TLS Record Protocol 是分层协议. 在每一层, message 都可以包含 length, description 和 content 字段. Record Protocol 接收要传输的 message, 将数据分片为可管理的块, 可选压缩数据, 应用 MAC, 加密并传输结果. 接收到的数据会被解密, 验证, 解压缩, 重新组装, 然后交付给更高层 client.
本文档描述四个使用 Record Protocol 的协议: handshake protocol, alert protocol, change cipher spec protocol 和 application data protocol. 为允许 TLS protocol 扩展, Record Protocol 可以支持额外 record content type. 新 record content type value 由 IANA 在 TLS Content Type Registry 中分配.
实现不得发送本文档未定义的 record type, 除非某个 extension 已协商该类型. TLS 实现收到 unexpected record type 时, 必须发送 unexpected_message alert.
任何设计为在 TLS 上使用的协议都必须仔细处理所有可能攻击. 实践中, 这意味着 protocol designer 必须了解 TLS 提供哪些安全属性, 不提供哪些安全属性, 并且不能安全依赖后者.
特别注意, record 的 type 和 length 不受加密保护. 如果这些信息本身敏感, application designer 可能需要采取 padding 或 cover traffic 等措施减少信息泄露.
6.1. 连接状态 (Connection States)
TLS connection state 是 TLS Record Protocol 的运行环境. 它指定 compression algorithm, encryption algorithm 和 MAC algorithm, 并包含这些 algorithm 的参数, 包括 MAC key 和 connection 读写两个方向的 bulk encryption key.
逻辑上始终存在四个 connection state: current read state, current write state, pending read state, pending write state. 所有 record 都在 current read/write state 下处理. pending state 的 security parameter 可由 TLS Handshaking protocol 设置, ChangeCipherSpec 可以选择性地把某个 pending state 变为 current state.
TLS Connection read/write state 的 security parameter 包括:
- connection end: 当前实体在此 connection 中是 client 还是 server.
- PRF algorithm: 从 master secret 生成 key 的 algorithm.
- bulk encryption algorithm: 用于 bulk encryption 的 algorithm.
- MAC algorithm: 用于 message authentication 的 algorithm.
- compression algorithm: 用于 data compression 的 algorithm.
- master secret: 两个 peer 共享的 48-byte secret.
- client random: client 提供的 32-byte 值.
- server random: server 提供的 32-byte 值.
这些参数用 presentation language 定义为:
enum { server, client } ConnectionEnd;
enum { tls_prf_sha256 } PRFAlgorithm;
enum { null, rc4, 3des, aes }
BulkCipherAlgorithm;
enum { stream, block, aead } CipherType;
enum { null, hmac_md5, hmac_sha1, hmac_sha256,
hmac_sha384, hmac_sha512} MACAlgorithm;
enum { null(0), (255) } CompressionMethod;
struct {
ConnectionEnd entity;
PRFAlgorithm prf_algorithm;
BulkCipherAlgorithm bulk_cipher_algorithm;
CipherType cipher_type;
uint8 enc_key_length;
uint8 block_length;
uint8 fixed_iv_length;
uint8 record_iv_length;
MACAlgorithm mac_algorithm;
uint8 mac_length;
uint8 mac_key_length;
CompressionMethod compression_algorithm;
opaque master_secret[48];
opaque client_random[32];
opaque server_random[32];
} SecurityParameters;
record layer 使用 security parameter 生成 client/server write MAC key, client/server write encryption key, 以及 client/server write IV. client write parameter 由 server 接收和处理 record 时使用, 反之亦然.
每个 connection state 包含 compression state, cipher state, MAC key 和 sequence number. sequence number 分别为 read/write state 维护, 每当 connection state 变为 active state 时必须设为零. sequence number 类型为 uint64, 不回绕. 如果 TLS 实现需要回绕 sequence number, 必须重新协商.
6.2. 记录层 (Record Layer)
TLS record layer 从高层接收任意大小的非空未解释数据块.
6.2.1. 分片 (Fragmentation)
record layer 将信息块分片成 TLSPlaintext record, 每个 record 承载不超过 2^14 byte 的数据块. client message boundary 不在 record layer 中保留.
struct {
uint8 major;
uint8 minor;
} ProtocolVersion;
enum {
change_cipher_spec(20), alert(21), handshake(22),
application_data(23), (255)
} ContentType;
struct {
ContentType type;
ProtocolVersion version;
uint16 length;
opaque fragment[TLSPlaintext.length];
} TLSPlaintext;
type: 用于处理封装 fragment 的高层协议.
version: 正在使用的协议版本. 本文档描述 TLS Version 1.2, 其版本为 {3, 3}.
length: 后续 TLSPlaintext.fragment 的 byte 长度. 该长度不得超过 2^14.
fragment: application data. 该数据对 TLS 透明, 作为独立块交由 type 字段指定的高层协议处理.
实现不得发送 Handshake, Alert 或 ChangeCipherSpec content type 的零长度 fragment. Application data 的零长度 fragment 可以发送, 因为它们可作为流量分析对抗措施.
不同 TLS record layer content type 的数据可以交错. Application data 通常比其他 content type 的传输优先级低. 但是 record 不得跨越 ChangeCipherSpec message boundary.
6.2.2. 记录压缩和解压缩 (Record Compression and Decompression)
所有 record 都使用当前 session state 中定义的 compression algorithm 压缩. 始终存在一个 active compression algorithm, 初始定义为 CompressionMethod.null. compression algorithm 将 TLSPlaintext 转换为 TLSCompressed. compression 必须无损, 且不得使 content length 增加超过 1024 byte.
CompressionMethod.null 是 identity operation, 不改变任何字段.
6.2.3. 记录载荷保护 (Record Payload Protection)
encryption 和 MAC function 将 TLSCompressed 转换为 TLSCiphertext. decryption function 执行反向过程. record 的 MAC 也包含 sequence number, 以便检测缺失, 额外或重复 message.
struct {
ContentType type;
ProtocolVersion version;
uint16 length;
select (SecurityParameters.cipher_type) {
case stream: GenericStreamCipher;
case block: GenericBlockCipher;
case aead: GenericAEADCipher;
} fragment;
} TLSCiphertext;
TLS 1.2 支持 stream cipher, CBC block cipher 和 AEAD cipher 三种保护形式. stream cipher 在加密前计算 MAC. CBC block cipher 使用显式 IV 和 padding, receiver 必须检查 padding 并在错误时返回 bad_record_mac alert. 为防御 CBC padding timing attack, 实现必须尽量使 record processing time 与 padding 是否正确无关. AEAD cipher 同时提供加密和完整性保护, 并以 sequence number, type, version 和 length 作为 additional authenticated data.
6.3. 密钥计算 (Key Calculation)
Record Protocol 需要一种 algorithm, 从 handshake protocol 提供的 security parameter 生成当前 connection state 所需的 key.
master secret 被扩展为安全 byte 序列, 然后按顺序拆分为 client write MAC key, server write MAC key, client write encryption key, server write encryption key, 以及可能的 client/server write IV.
key material 计算如下:
key_block = PRF(SecurityParameters.master_secret,
"key expansion",
SecurityParameters.server_random +
SecurityParameters.client_random);
然后 key_block 按如下顺序划分:
client_write_MAC_key[SecurityParameters.mac_key_length]
server_write_MAC_key[SecurityParameters.mac_key_length]
client_write_key[SecurityParameters.enc_key_length]
server_write_key[SecurityParameters.enc_key_length]
client_write_IV[SecurityParameters.fixed_iv_length]
server_write_IV[SecurityParameters.fixed_iv_length]
当前最大 key material 需求来自 AES_256_CBC_SHA256. 它需要两个 32 byte key 和两个 32 byte MAC key, 总计 128 byte key material. exportable encryption algorithm 已不再支持, 新实现不应该使用 export cipher.