[Crypto] 御网杯 ECDSA Nonce

👁 0 views
📅 2025-5-30 ⏱ < 1 min 🏆 御网杯

ECDSA Nonce 重用攻击 — 解题思路

1. 识别漏洞

challenge.jsonsignature1_rsignature2_r 完全相同,说明两次签名使用了相同的随机数(nonce)k。这是 ECDSA 最严重的密钥泄露漏洞。

2. ECDSA 签名公式回顾

ECDSA 签名 $(r, s)$ 的计算方式:

$$s = k^{-1} \cdot (z + r \cdot d) \mod n$$

其中:

  • $k$ = 随机数(nonce)
  • $z$ = 消息的哈希值(SHA-256)
  • $r$ = $(k \cdot G)_x$
  • $d$ = 私钥
  • $n$ = 曲线阶

3. 数学推导(当 $r_1 = r_2$ 时)

对两条消息分别有: $$s_1 = k^{-1} \cdot (z_1 + r \cdot d) \mod n$$ $$s_2 = k^{-1} \cdot (z_2 + r \cdot d) \mod n$$

第一步:恢复 nonce $k$

两式相减: $$s_1 - s_2 = k^{-1} \cdot (z_1 - z_2) \mod n$$

因此: $$k = (z_1 - z_2) \cdot (s_1 - s_2)^{-1} \mod n$$

第二步:恢复私钥 $d$

从第一个签名公式: $$s_1 = k^{-1} \cdot (z_1 + r \cdot d) \mod n$$

整理得: $$d = (s_1 \cdot k - z_1) \cdot r^{-1} \mod n$$

4. 关键实现细节

  • 消息需要先做 SHA-256 哈希:ECDSA 中 $z = H(m)$,不是原始消息的整数值
  • 使用 Python 内置的 pow(a, -1, n) 计算模逆
  • eccdsa 库验证:计算 $d \cdot G$ 是否等于给定公钥

5. 验证结果

| 项目 | 值 | |------|-----| | 恢复的私钥 | 23c559c4d212862cf3cb29c2bc4bc1b1683244b523783aa4bd25d24893fdb280 | | 计算的公钥 x | 50375119028105999887364047539655247182204094206523319300435263028224430946911 | | 计算的公钥 y | 108951950523016877465488279015105781644805040421399966844862347172473790727509 | | 公钥匹配 | ✅ 完全一致 |

6. 最终 Flag

flag{ecdsa_nonce_reuse_23c559c4d212862cf3cb29c2bc4bc1b1683244b523783aa4bd25d24893fdb280}