Security2 min
CVE-2020-28498 — elliptic (npm) ECDH Invalid Curve Attack
Breaks down the private-key leakage risk in the elliptic library caused by missing invalid-curve validation in ECDH, along with the corresponding fix and mitigations.
JS 生态最著名的椭圆曲线库
elliptic(底层依赖bn.js大数库),其derive()在 ECDH 时未校验公钥点是否落在 secp256k1 曲线上,导致私钥可被无效曲线攻击恢复。这是「JS 数学库 + CRT 还原私钥」这一题的最经典代表。
1. 基本信息
| 项 | 值 |
|---|---|
| CVE | CVE-2020-28498 |
| GitHub Advisory | GHSA-r9p9-mrjm-926w |
| 影响包 | elliptic(npm) |
| 漏洞类型 | CWE-327(使用已破解/有风险的加密算法) |
| 严重度 | CVSS 3.1:AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:N/A:N |
| 发布时间 | 2021-02-02(漏洞存在于 < 6.5.4) |
受影响版本 & 修复
| 版本区间 | 修复版本 |
|---|---|
0 ~ 6.5.3 | 6.5.4 |
2. 漏洞成因
在 lib/elliptic/ec/key.js 的 derive()(ECDH)里,没有调用曲线点校验,就把对方公钥直接拿去做了标量乘法:
// 伪代码示意
KeyPair.prototype.derive = function (pub) {
// 缺少:this.curve.validate(pub.getPoint()) ❌
return this.priv.mul(pub.getPoint()); // S = [d]·P
};
修复(PR #244,commit 441b7428)补上了 curve.validate(...),确认点确实在 secp256k1 曲线上。
3. 利用原理
原理与 无效曲线攻击与CRT私钥恢复.md 完全一致:
- 攻击者发送一个不在 secp256k1 曲线上的点 (落在扭曲线或低阶子群上,阶为小整数 );
- 受害者算 ;
- 因 , 只泄漏 ;
- 换不同的小阶 重复,收集 ;
- CRT 合并还原 。
该 CVE 官方参考直接引用了 Christian Lundkvist 的《secp256k1 twist attacks》博客,完整描述了这套扭曲线 + CRT 的恢复方法。
4. 攻击流程
flowchart TD
A["发送不在 secp256k1 上的点 P(扭曲线/低阶子群)"] --> B["derive() 未校验,直接算 S = [d]P"]
B --> C["S 只泄漏 r = d mod l"]
C --> D["换不同小阶 li 重复"]
D --> E["CRT 合并 ri → 私钥 d"]
5. 影响
- 任何使用受影响
elliptic做 ECDH 的应用(大量钱包、签名库、区块链工具链间接依赖它); - 攻击者无需权限即可在多次 ECDH 交互后恢复私钥。
6. 修复
- 升级到
elliptic@6.5.4及以上; - 如无法立即升级,在调用
derive()前自行用curve.validate(point)校验对方公钥。
7. 参考
- NVD:https://nvd.nist.gov/vuln/detail/CVE-2020-28498
- GitHub Advisory:https://github.com/indutny/elliptic/security/advisories/GHSA-r9p9-mrjm-926w
- 修复 commit:https://github.com/indutny/elliptic/commit/441b7428b0e8f6636c42118ad2aaa186d3c34c3f
- twist 攻击原理:https://github.com/christianlundkvist/blog/blob/master/2020_05_26_secp256k1_twist_attacks/secp256k1_twist_attacks.md
- Snyk:https://snyk.io/vuln/SNYK-JS-ELLIPTIC-1064899