本节摘要:SOURCE 4.3:计时、功耗、电磁泄漏可攻破「数学上安全」的实现。格方案需恒定时间、掩码与盲化。本节对比算法安全 vs 实现安全。
| 信道 | 手段 | 后果 |
|---|---|---|
| 计时 | 缓存命中差异 | 私钥泄露 |
| 功耗 | SPA/DPA | 签名 nonce 恢复 |
| 电磁 | 近场探测 | 密钥位提取 |
| 技术 | 作用 |
|---|---|
| 恒定时间 | 分支/内存访问与密钥无关 |
| 掩码 | 中间值随机分享 |
| 盲化 | 私钥运算加随机 |
# 反例:非恒定时间比较 # if secret[i] == guess[i]: ... # 泄漏 i # 正例:恒定时间 compare(概念) # result = constant_time_eq(a, b)
⚠️ 常见坑:只通过 KAT 不测 dudect/timing——线上可被本地攻击者读密钥。
💡 关键直觉:PQC 密钥更大,实现泄漏面也更大;hardening 是必选项。
格密码的实现比 RSA/ECC 更容易引入侧信道泄漏,原因在于它的数据路径复杂且与密钥强相关。Kyber 的解封装要对密文做多项式的逆变换与带误差比较,Dilithium 的签名过程中存在依赖秘密向量重分布的拒绝采样分支——这些操作一旦出现「分支条件依赖秘密数据」或「内存访问索引依赖秘密数据」,计时与缓存侧信道就能把密钥信息一点点带出去。
恒定时间编程的基本纪律有三条:不依据秘密值做条件跳转、不依据秘密值做内存索引、不依据秘密值提前返回。表面简单,实际执行时很容易被编译器优化破坏,因此业界依赖工具链层面的保障:使用验证过的实现库、在关键路径上显式使用恒定时间比较原语、配合 dudect 等测试工具对实现做统计性时序分析。KAT 正确性测试与侧信道测试是两个正交的维度,前者保证「算得对」,后者保证「不泄漏」。
# 侧信道防护自检清单 1. 确认关键路径无秘密相关的分支跳转(审查汇编或源码) 2. 确认多项式索引访问不依赖秘密值(无 secret 下标) 3. 用恒定时间比较函数替代逐字节 if 比较 4. 运行 dudect / ctgrind 等时序统计测试 5. 对高威胁场景评估掩码(masked)实现方案 6. 记录编译选项与优化级别,防止优化破坏恒定时间 7. 优先选用 liboqs 等经社区审计的成熟实现
对选择「自己写一个 Kyber」的团队,这七个检查项是底线而非可选项。更现实的建议是直接基于 liboqs 或 PQClean 集成,把侧信道防护交给经过社区长期测试的代码,团队的精力放在协议集成与密钥管理上。算法在数学上是安全的,这句话只对正确且不泄漏的实现成立——这就是本节标题「实现安全」与「算法安全」必须分开对待的原因。
侧信道防护的强度应该与威胁模型匹配,而不是一律上最重的防护。基础威胁模型(远程攻击者、仅能观察网络流量)下,恒定时间实现配合标准密码库即可满足要求;本地攻击模型(攻击者可运行同机程序、监控计时与缓存)下,除了恒定时间,还需要掩码与内存隔离;物理攻击模型(设备落入攻击者手中,可测功耗与电磁)下,则需要掩码、随机化调度与硬件层面的防护。
这个梯度对预算决策很重要。IoT 设备单价低、数量大,物理攻击模型下每一分钱的防护成本都乘以出货量,所以通常会选择「硬件安全模块 + 软件恒定时间」的组合,而不是在每颗芯片上做完整掩码。云服务器是托管环境,远程与本地攻击模型为主,恒定时间加上库版本管控通常是足够且经济的起点。
# 威胁模型与防护等级对照 威胁模型 防护要求 典型场景 远程攻击者 恒定时间实现 + 审计库 公网 TLS 服务器 本地攻击者 恒定时间 + 掩码 + 隔离 多租户云主机 物理攻击者 掩码 + 硬件防护 + 随机化 IoT 设备、银行卡 侧信道审计 工具链验证 + 第三方审计 金融、政务系统
防护梯度的意义在于回答「花多少钱、防到什么程度」。把威胁模型写进需求文档,防护预算就有依据;没有威胁模型就开始堆防护,要么过度投入,要么留下与实际风险不匹配的缺口。这是把侧信道从「学术话题」变成「工程预算问题」的关键一步。