ECDSA 随机数 k 是什么
ECDSA 签名需要每个签名一个的一次性随机数 k,签名结果 (r, s) 中的 r 由 k 与基点运算得到。如果同一私钥下两次签名使用了相同的 k,攻击者用两条签名的 s 值就能解出私钥,这是纯数学推导,不需要任何额外假设。工程上的正确做法是使用 RFC 6979 的确定性 k 派生,或直接调用成熟库,不要自行生成随机数。
基本信息
| 核心规则 | 同一私钥下 k 必须唯一且不可预测 |
|---|---|
| 确定性方案 | RFC 6979:由私钥与消息散列派生 k |
| 历史案例 | 2010 年 PS3 因 k 固定导致私钥被恢复 |
| 现代替代 | Ed25519 等方案从设计上消除随机数依赖 |
典型使用场景
- 签名服务:多实例与容器复制后随机状态可能重复,需要评估熵源
- 硬件签名设备:确认固件使用合规随机源
- 代码审计:重点查看自行实现的 k 生成逻辑
- 区块链与数字签名场景:k 复用会直接造成资产损失
- 迁移评估:从 ECDSA 迁到 Ed25519 以消除随机数依赖
交给成熟库处理
交给成熟库处理
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec
private_key = ec.generate_private_key(ec.SECP256R1())
signature = private_key.sign(data, ec.ECDSA(hashes.SHA256())) # 库内部安全处理 k
private_key.public_key().verify(signature, data, ec.ECDSA(hashes.SHA256()))风险来源与对策
| 风险来源 | 表现 | 对策 |
|---|---|---|
| 随机源故障 | 两次签名 k 相同 | 使用 RFC 6979 或成熟库 |
| 快照回滚 | 随机状态重复 | 评估熵源质量,避免克隆后直接签名 |
| 自制生成逻辑 | 取模偏置或可预测 | 不要自行实现,交由库处理 |
| 侧信道 | 时序与功耗泄漏 | 使用常量时间实现或硬件模块 |
私钥恢复只需要两条签名:一旦 k 重复,攻击者不必暴力破解,直接联立方程即可得到私钥,因此 k 的质量直接等于私钥的安全。
落地检查项
- 确认签名代码来自成熟库而不是自研实现
- 检查设备或容器重启后的随机源状态
- 对高价值密钥使用硬件模块或 HSM
- 定期审计签名服务的实现版本与已知漏洞
RFC 6979 的确定性方案把 k 绑定到私钥与消息散列,同一消息重复签名得到相同结果,既避免了随机源故障,也便于测试复现。