密码学没有万能银弹
1 简介
密码学没有绝对的"银弹",GCM是当前的默认最佳实践,但理解CTR等其他模式的价值,能让您在特定场景做出更精准的技术选型。OFB则因缺乏独特优势,在现代密码工程中确实逐渐淡出视野。

2 CTR(Counter Mode) 工作原理
Ci = Pi ⊕ SM4(K, Nonce || Counter)
- 特点
把 SM4 当 高性能流密码
完全可并行
-
安全性
高(仅加密)
Nonce 不能重复
不提供完整性
- 优点
高性能
并行
无填充
- 缺点
需配合 MAC
不防篡改,重放攻击
应用
高速通信
数据存储加密(需 MAC)
3 GCM的限制与CTR的适用场景:
- 场景1:纯加密需求(无需认证)
某些特殊场景只需要机密性
场景:加密随机数生成器的内部状态
state = get_random_state()
选项A:GCM(过度设计)
ciphertext, tag = sm4_gcm_encrypt(state, key, nonce)
产生了不必要的认证标签,增加开销
选项B:CTR(恰到好处)
ciphertext = sm4_ctr_encrypt(state, key, nonce)
更简洁,无认证开销
适用场景:
内部数据混淆(如白盒密码)
随机数生成器的状态加密
已通过其他机制保证完整性的场景
- 场景2:需要自定义认证逻辑
场景:分布式存储系统,需要先加密后生成存储指纹
data = read_large_file()
步骤1:CTR加密(可并行加速)
encrypted_data = sm4_ctr_parallel_encrypt(data, key, nonce)
步骤2:自定义完整性保护(如Merkle树)
可以分批计算哈希,支持增量更新
merkle_root = build_merkle_tree(encrypted_data)
而GCM必须一次性处理整个消息才能生成认证标签
对大文件不友好
场景3:资源极度受限环境
物联网节点配置:
- RAM: 2KB
- Flash: 16KB
- 功耗:微安级别
GCM的问题:
- 需要存储GHASH表(额外的内存)
- 乘法和模运算较复杂(功耗高)
- 认证标签固定128位(可能过长)
CTR+简化MAC的替代方案:
- CTR加密(流式,内存友好)
- 使用轻量级MAC(如Poly1305,比GHASH简单)
- 可调整认证标签长度
场景4:需要独立控制加密和认证密钥
某些安全协议要求密钥分离
enc_key = derive_key(master_key, "encryption")
auth_key = derive_key(master_key, "authentication")
CTR+HMAC方案:
ciphertext = sm4_ctr_encrypt(plaintext, enc_key, nonce)
tag = hmac_sm3(auth_key, ciphertext) # 明确分离
- GCM方案:
加密和认证使用同一个密钥
无法满足"密钥分离"的安全要求
3 GCM自身的限制:
- Nonce长度限制
GCM标准:Nonce推荐96位(12字节)
- 如果使用其他长度,需要额外哈希计算
- 计数器只有32位,限制单个密钥加密数据量:2³²个块 ≈ 68GB
CTR模式:可灵活设计计数器大小
- 可根据需要设计64位、128位计数器
- 更适合超大数据量加密
- 性能不是总最优
小消息性能对比(< 64字节)
GCM开销:加密 + GHASH + 最终处理
CTR+HMAC开销:加密 + HMAC初始化 + 更新 + 完成
在某些硬件上,对小消息:
CTR+硬件加速的AES + 硬件加速的HMAC > GCM
- 实现复杂性更高
GCM实现需要多个组件
void gcm_encrypt() {
ghash_init(); // GHASH初始化
ctr_encrypt(); // CTR加密
ghash_update(); // 更新GHASH
gmac_finalize(); // 生成GMAC
// 需要防时序攻击
}
CTR+HMAC实现相对独立
void ctr_hmac_encrypt() {
ctr_encrypt(); // CTR加密(可独立优化)
hmac_init(); // HMAC初始化(可独立优化)
hmac_update(); // HMAC更新
hmac_final(); // HMAC完成
}
4 现代密码学的分层选择策略
决策树:如何选择模式?
是否需要认证?
├── 否 → 纯加密模式
│ ├── 需要并行/随机访问? → CTR
│ ├── 需要自同步? → CFB
│ └── 特殊需求(预计算) → OFB(极少用)
│
└── 是 → 认证加密模式
├── 标准通用场景 → GCM(首选)
├── 需要密钥分离/灵活控制 → CTR + HMAC
├── 资源极度受限 → ChaCha20-Poly1305(流密码方案)
└── 特定国密要求 → SM4-GCM 或 SM4+SM3-HMAC
具体推荐场景:
首选GCM的场景:
TLS/SSL通信:TLS 1.3强制使用AEAD(GCM或ChaCha20-Poly1305)
磁盘全盘加密:需要简单统一的加密认证
API传输加密:HTTP请求体加密认证
大多数新系统设计:符合"安全默认化"原则
考虑CTR+HMAC的场景:
自定义存储格式:需要灵活的数据组织
分层安全架构:明确分离加密和认证职责
兼容老系统:逐步迁移的过渡方案
特定性能需求:对并行化有极致要求
几乎不使用OFB的场景:
新系统设计:无优势
遗留系统维护:仅在必须兼容时使用
学术研究:作为密码学教学模式
5 国密场景下的实际选择
国密标准GB/T 17964-2021的实际指导:
优先级1(推荐新系统使用):
- SM4-GCM: 综合最优,国密标准GB/T 36624-2018
- SM4-CCM: 适合资源受限环境
优先级2(现有系统升级):
- SM4-CTR + HMAC-SM3: 明确分离加密认证
- SM4-CBC + HMAC-SM3: 兼容传统模式
优先级3(特定需求):
- SM4-CFB: 自同步流加密(如不可靠信道)
- SM4-OFB: 几乎不用,除非特殊协议要求
避免使用:
- 纯SM4-ECB: 完全不安全
- 纯SM4-CBC/CFB/OFB: 缺乏完整性保护
实际工程建议:
90%场景用这个:
ciphertext, tag = sm4_gcm_encrypt(data, key, nonce, aad)
5%特殊场景用这个:
ciphertext = sm4_ctr_encrypt(data, enc_key, nonce)
mac = hmac_sm3(auth_key, ciphertext)
5%遗留兼容:
可能用到CFB,但必须配HMAC
几乎不用OFB
常见问题
- 为什么没OFB模式?
OFB有理论价值但无工程优势,处在尴尬的中间位置
错误不传播的特性在现代是缺陷而非优点
串行依赖无法利用现代硬件并行能力
- GCM不是最优选择吗?
对大多数新系统,GCM是最优选择
但在需要密钥分离、自定义认证、特殊性能优化时,CTR+HMAC更灵活
GCM有Nonce长度、实现复杂度等限制
- 点赞
- 收藏
- 关注作者
评论(0)