TLS加密算法深度解析

TLS 加密算法深度解析

从数学原理到工程实现,探索现代密码学在 TLS 中的应用

加密算法体系

对称加密算法

AES (Advanced Encryption Standard)

密钥长度:128/192/256 位
分组长度:128 位
轮数:10/12/14 轮

工作模式对比

模式 特点 安全性 性能 适用场景
CBC 需要 IV,串行 中等 已淘汰
GCM 认证加密,并行 TLS 1.2+
CCM 认证加密,串行 中等 受限环境
ChaCha20-Poly1305 流密码+认证 移动设备

非对称加密算法

RSA

# RSA 密钥生成
def generate_rsa_key(bits=2048):
    # 1. 选择两个大质数 p, q
    p = generate_prime(bits // 2)
    q = generate_prime(bits // 2)
    
    # 2. 计算模数 n = p * q
    n = p * q
    
    # 3. 计算欧拉函数 φ(n) = (p-1)(q-1)
    phi_n = (p - 1) * (q - 1)
    
    # 4. 选择公钥指数 e (通常是 65537)
    e = 65537
    
    # 5. 计算私钥指数 d = e^(-1) mod φ(n)
    d = mod_inverse(e, phi_n)
    
    return {
        'public_key': (n, e),
        'private_key': (n, d)
    }

椭圆曲线密码学 (ECC)

# 椭圆曲线点运算
class EllipticCurve:
    def __init__(self, a, b, p):
        self.a = a  # 曲线参数
        self.b = b  # 曲线参数  
        self.p = p  # 有限域模数
    
    def point_add(self, P, Q):
        """椭圆曲线点加法"""
        if P is None:
            return Q
        if Q is None:
            return P
        
        x1, y1 = P
        x2, y2 = Q
        
        if x1 == x2:
            if y1 == y2:
                # 点倍乘
                s = (3 * x1 * x1 + self.a) * mod_inverse(2 * y1, self.p) % self.p
            else:
                # 相反点,结果为无穷远点
                return None
        else:
            # 普通点加法
            s = (y2 - y1) * mod_inverse(x2 - x1, self.p) % self.p
        
        x3 = (s * s - x1 - x2) % self.p
        y3 = (s * (x1 - x3) - y1) % self.p
        
        return (x3, y3)
    
    def scalar_multiply(self, k, P):
        """标量乘法 kP"""
        if k == 0:
            return None
        
        result = None
        addend = P
        
        while k:
            if k & 1:
                result = self.point_add(result, addend)
            addend = self.point_add(addend, addend)
            k >>= 1
        
        return result

哈希算法

SHA-2 家族

SHA-224: 224 位输出
SHA-256: 256 位输出 (TLS 常用)
SHA-384: 384 位输出
SHA-512: 512 位输出

SHA-3 (Keccak)

  • 不同于 SHA-2 的 Merkle-Damgård 结构
  • 使用海绵函数构造
  • 抗长度扩展攻击

密钥交换算法

ECDHE (椭圆曲线 Diffie-Hellman)

数学原理

1. 双方约定椭圆曲线 E 和基点 G
2. Alice 生成私钥 a,计算公钥 A = aG
3. Bob 生成私钥 b,计算公钥 B = bG  
4. Alice 计算共享密钥 K = aB = a(bG) = abG
5. Bob 计算共享密钥 K = bA = b(aG) = abG

安全性基础

  • 椭圆曲线离散对数问题 (ECDLP)
  • 给定 P, Q,求 k 使得 Q = kP 在计算上不可行

常用曲线

P-256 (secp256r1): y² = x³ - 3x + b (mod p)
P-384 (secp384r1): 更高安全强度
Ed25519: 扭曲爱德华曲线,性能优异

DHE (有限域 Diffie-Hellman)

数学原理

1. 选择大质数 p 和生成元 g
2. Alice 生成私钥 a,计算公钥 A = g^a mod p
3. Bob 生成私钥 b,计算公钥 B = g^b mod p
4. 共享密钥 K = g^(ab) mod p

安全参数

  • 2048 位模数提供 112 位安全强度
  • 3072 位模数提供 128 位安全强度

数字签名算法

ECDSA (椭圆曲线数字签名)

签名过程

def ecdsa_sign(message, private_key, curve):
    # 1. 计算消息哈希
    h = sha256(message)
    
    # 2. 生成随机数 k
    k = random.randint(1, curve.order - 1)
    
    # 3. 计算 r = (kG).x mod n
    point = curve.scalar_multiply(k, curve.generator)
    r = point[0] % curve.order
    
    # 4. 计算 s = k^(-1)(h + r * private_key) mod n
    k_inv = mod_inverse(k, curve.order)
    s = (k_inv * (h + r * private_key)) % curve.order
    
    return (r, s)

验证过程

def ecdsa_verify(message, signature, public_key, curve):
    r, s = signature
    h = sha256(message)
    
    # 计算 w = s^(-1) mod n
    w = mod_inverse(s, curve.order)
    
    # 计算 u1 = hw mod n, u2 = rw mod n
    u1 = (h * w) % curve.order
    u2 = (r * w) % curve.order
    
    # 计算 (x, y) = u1*G + u2*public_key
    point1 = curve.scalar_multiply(u1, curve.generator)
    point2 = curve.scalar_multiply(u2, public_key)
    point = curve.point_add(point1, point2)
    
    # 验证 x ≡ r (mod n)
    return point[0] % curve.order == r

EdDSA (爱德华曲线数字签名)

Ed25519 优势

def ed25519_sign(message, private_key):
    # 1. 确定性随机数生成
    r = hash(private_key_suffix + message)
    
    # 2. 计算 R = rG
    R = scalar_multiply(r, generator)
    
    # 3. 计算挑战值
    h = hash(R + public_key + message)
    
    # 4. 计算签名
    s = (r + h * private_key) % order
    
    return (R, s)

特点

  • 确定性签名(相同输入产生相同签名)
  • 抗侧信道攻击
  • 更快的签名和验证速度

认证加密 (AEAD)

AES-GCM

工作原理

GCM = CTR 模式加密 + GHASH 认证

实现细节

def aes_gcm_encrypt(plaintext, key, iv, aad=b''):
    # 1. 生成认证密钥 H
    H = aes_encrypt(b'\x00' * 16, key)
    
    # 2. CTR 模式加密
    ciphertext = aes_ctr_encrypt(plaintext, key, iv)
    
    # 3. GHASH 计算认证标签
    auth_data = aad + b'\x00' * padding_length(aad)
    auth_data += ciphertext + b'\x00' * padding_length(ciphertext)
    auth_data += struct.pack('>QQ', len(aad) * 8, len(ciphertext) * 8)
    
    tag = ghash(auth_data, H)
    
    return ciphertext, tag

ChaCha20-Poly1305

ChaCha20 流密码

def chacha20_encrypt(plaintext, key, nonce, counter=0):
    keystream = b''
    for i in range((len(plaintext) + 63) // 64):
        block = chacha20_block(key, nonce, counter + i)
        keystream += block
    
    return bytes(a ^ b for a, b in zip(plaintext, keystream))

Poly1305 认证

def poly1305_mac(message, key):
    r = int.from_bytes(key[:16], 'little') & 0x0ffffffc0ffffffc0ffffffc0fffffff
    s = int.from_bytes(key[16:32], 'little')
    
    accumulator = 0
    for i in range(0, len(message), 16):
        block = message[i:i+16] + b'\x01'
        n = int.from_bytes(block, 'little')
        accumulator = ((accumulator + n) * r) % (2**130 - 5)
    
    return ((accumulator + s) % 2**128).to_bytes(16, 'little')

密钥派生

TLS 1.2 PRF

伪随机函数

def tls12_prf(secret, label, seed, length):
    """TLS 1.2 伪随机函数"""
    def p_hash(secret, seed, length):
        result = b''
        a = seed
        while len(result) < length:
            a = hmac_sha256(secret, a)
            result += hmac_sha256(secret, a + seed)
        return result[:length]
    
    return p_hash(secret, label + seed, length)

# 主密钥派生
master_secret = tls12_prf(
    pre_master_secret,
    b"master secret",
    client_random + server_random,
    48
)

# 会话密钥派生
key_block = tls12_prf(
    master_secret,
    b"key expansion", 
    server_random + client_random,
    key_block_length
)

TLS 1.3 HKDF

基于 HMAC 的密钥派生

def hkdf_extract(salt, ikm):
    """HKDF 提取阶段"""
    if not salt:
        salt = b'\x00' * hash_length
    return hmac(salt, ikm)

def hkdf_expand(prk, info, length):
    """HKDF 扩展阶段"""
    t = b''
    okm = b''
    counter = 1
    
    while len(okm) < length:
        t = hmac(prk, t + info + bytes([counter]))
        okm += t
        counter += 1
    
    return okm[:length]

# TLS 1.3 密钥派生
early_secret = hkdf_extract(b'', psk or b'\x00' * hash_length)
handshake_secret = hkdf_extract(derive_secret(early_secret, "derived"), ecdhe_shared_secret)
master_secret = hkdf_extract(derive_secret(handshake_secret, "derived"), b'\x00' * hash_length)

性能优化

硬件加速

AES-NI 指令集

// Intel AES-NI 示例
__m128i aes_encrypt_block(__m128i plaintext, __m128i* round_keys) {
    __m128i state = _mm_xor_si128(plaintext, round_keys[0]);
    
    for (int i = 1; i < 10; i++) {
        state = _mm_aesenc_si128(state, round_keys[i]);
    }
    
    return _mm_aesenclast_si128(state, round_keys[10]);
}

椭圆曲线优化

  • 蒙哥马利阶梯算法
  • 窗口方法
  • 预计算表

算法选择建议

高性能场景

密钥交换: X25519 (ECDHE)
签名: Ed25519
对称加密: ChaCha20-Poly1305 (移动端)
         AES-256-GCM (服务器端)
哈希: SHA-256

兼容性优先

密钥交换: P-256 (ECDHE)
签名: ECDSA P-256
对称加密: AES-128-GCM
哈希: SHA-256

安全考量

侧信道攻击防护

常数时间实现

def constant_time_compare(a, b):
    """常数时间字符串比较"""
    if len(a) != len(b):
        return False
    
    result = 0
    for x, y in zip(a, b):
        result |= x ^ y
    
    return result == 0

def constant_time_select(condition, a, b):
    """常数时间条件选择"""
    mask = -(condition & 1)  # 0 或 0xFFFFFFFF
    return (a & mask) | (b & ~mask)

随机数生成

密码学安全随机数

import os
import hashlib

def secure_random(length):
    """生成密码学安全的随机数"""
    return os.urandom(length)

def deterministic_random(seed, length):
    """确定性随机数生成(用于测试)"""
    output = b''
    counter = 0
    while len(output) < length:
        hash_input = seed + counter.to_bytes(4, 'big')
        output += hashlib.sha256(hash_input).digest()
        counter += 1
    return output[:length]

后量子密码学

NIST 标准化算法

CRYSTALS-Kyber (密钥封装)

  • 基于格密码学
  • 安全级别:Kyber512/768/1024
  • 抗量子攻击

CRYSTALS-Dilithium (数字签名)

  • 基于格密码学
  • 安全级别:Dilithium2/3/5
  • 签名长度较大

混合部署策略

class HybridKeyExchange:
    def __init__(self):
        self.classical = ECDHE_P256()
        self.post_quantum = Kyber768()
    
    def generate_keys(self):
        # 生成两套密钥对
        classical_keys = self.classical.generate_keypair()
        pq_keys = self.post_quantum.generate_keypair()
        
        return {
            'classical': classical_keys,
            'post_quantum': pq_keys
        }
    
    def derive_shared_secret(self, my_keys, peer_public_keys):
        # 计算两个共享密钥
        classical_secret = self.classical.compute_shared_secret(
            my_keys['classical']['private'],
            peer_public_keys['classical']
        )
        
        pq_secret = self.post_quantum.decapsulate(
            my_keys['post_quantum']['private'],
            peer_public_keys['post_quantum']
        )
        
        # 组合两个密钥
        combined_secret = hkdf_extract(
            classical_secret,
            pq_secret
        )
        
        return combined_secret

总结

现代 TLS 加密算法的选择原则:

  1. 对称加密:优先 AEAD 模式(AES-GCM、ChaCha20-Poly1305)
  2. 非对称加密:ECDHE + ECDSA/EdDSA,逐步淘汰 RSA
  3. 哈希算法:SHA-256 为主,SHA-3 备选
  4. 性能优化:利用硬件加速,选择高效曲线
  5. 未来准备:关注后量子算法,准备混合部署

理解这些算法的数学原理和工程实现,有助于做出正确的安全配置选择。