本列表收录了存在潜在不安全的 ed25519 签名库,这些库提供了一个公共 API,允许将私钥和公钥作为签名函数的输入独立提供。误用这些公共 API 可能导致私钥泄露。
我们分析中的大多数仓库已收录于 IANIX :: 使用 Ed25519 的项目。
受影响库数量:45
公告发布后修复该问题的库数量:8
最后更新:2023 年 5 月 4 日
请注意,通常情况下,根据相关的 rfc8032,EdDSA 签名是确定性的,因此对于要签名的同一输入消息,会返回一个唯一的签名输出,其中包含两个元素:一个曲线点 R 和一个标量 S。
一个算法细节是,签名者的公钥只参与签名中 S 部分的确定性计算,而不参与 R 值的计算。后者意味着,如果攻击者能以某种方式将签名函数用作预言机(Oracle,接受任意公钥作为输入),那么对于同一条消息,有可能获得两个共享相同 R、仅在 S 部分有所不同的签名。遗憾的是,一旦发生这种情况,攻击者就可以轻松提取私钥;这篇 StackOverflow 帖子 解释了为何这是可行的。
话虽如此,公共 API 不应允许将解耦的私钥/公钥对作为签名输入。为了规避这一点,许多实现将公钥与私钥(或种子)一起存储,并将整个密钥对视为秘密,或者总是在签名函数内部重新派生公钥。不幸的是,大量现有库未能解决这个问题,它们允许任意公钥作为输入,却不检查输入的公钥是否与输入的私钥对应。
当然,这并不意味着所有依赖这些库的应用程序都容易遭受密钥泄露攻击;实际上,大多数可能是安全的,因为通常不会向用户公开受影响的 API,并且会在调用 sign 之前将公钥/私钥对绑定在一起。另一方面,即使这些 API 未公开,也有一些应用程序在私钥和公钥的管理与存储方面采用了不同的 TCB 威胁模型策略。话虽如此,为防止此攻击,开发人员还应对公钥强制执行完整性保护协议。
在此,我们列出一些受影响的库及其相关代码引用。
图 1. ed25519-dalek Rust crate 中 API 误用的示例。
C: OpenGNB
https://github.com/gnbdev/opengnb/blob/master/libs/ed25519/sign.c#L7
C: GNU Nettle
https://github.com/gnutls/nettle/blob/fe7ae87d1b837e82f7c7968b068bca7d853a4cec/ed25519-sha512-sign.c#L43
ASM/C: iroha-ed25519(Hyperledger 项目)
https://github.com/hyperledger/iroha-ed25519/blob/main/lib/ed25519/ref10/ed25519.c#L27
以及
https://github.com/hyperledger/iroha-ed25519/blob/main/lib/ed25519/amd64-64-24k-pic/ed25519.c#L30
C: ed25519-donna (Andrew Moon)
https://github.com/floodyberry/ed25519-donna/blob/master/ed25519.c#L59
C: ed25519 (Orson Peters)
https://github.com/orlp/ed25519/blob/master/src/sign.c#L7
C: libbrine (Kevin Smith)
https://github.com/kevsmith/libbrine/blob/master/src/ed25519/sign.c#L7
C++: Ed25519 (ArduinoLibs)
https://rweather.github.io/arduinolibs/classEd25519.html#a36ecf67b4c5d2d39a31888f56af1f8a5
C#: ed25519 (Hans Wolff)
https://github.com/hanswolff/ed25519/blob/master/Ed25519/Ed25519.cs#L146
C#: Ed25519 (CryptoManiac)
https://github.com/CryptoManiac/Ed25519/blob/972829ac688847895d5105f19ca1e5777131b421/Chaos.NaCl/Internal/Ed25519Ref10/keypair.cs#L7
Dart: ed25519_dart (Oleksii Semeshchuk)
https://github.com/semolex/ed25519_dart/blob/master/lib/src/ed25519_dart_base.dart#L200
Dart: riclava_ed25519 (riclava)
https://github.com/riclava/ed25519/blob/master/lib/ed25519.dart#L125
Clojure: ed25519 (Kevin Downey)
https://github.com/hiredman/ed25519/blob/master/src/ed25519/core.clj#L168
Haskell: hs-scraps (Vincent Hanquez)
https://github.com/vincenthz/hs-scraps/blob/master/Crypto/Signature/Ed25519.hs#L115
Java: ed25519-java (k3d3)
https://github.com/k3d3/ed25519-java/blob/master/ed25519.java#L144
Java: ed25519 (Bjorn Arnelid)
https://github.com/BjornArnelid/ed25519/blob/master/src/ed25519/application/Ed25519.java#L32