JEP 339:爱德华曲线数字签名算法(EdDSA)
总结
使用 Edwards-Curve 数字签名算法(EdDSA)实现加密签名,具体描述见 RFC 8032。
目标
EdDSA 是一种现代的椭圆曲线签名方案,与 JDK 中现有的签名方案相比具有多个优势。本 JEP 的主要目标是根据 RFC 8032 实现这一标准化方案。这种新的签名方案并不会取代 ECDSA。
更多的实现目标:
-
开发一个平台无关的 EdDSA 实现,其性能优于现有的 ECDSA 实现(使用原生 C 代码),同时保持相同的安全强度。例如,在约 126 位安全强度下,使用 Curve25519 的 EdDSA 应该与在约 128 位安全强度下使用 secp256r1 曲线的 ECDSA 一样快。
-
确保运行时间与密钥无关,假设平台以恒定时间执行 64 位整数加法/乘法。此外,实现不会基于密钥进行分支判断。这些特性对于防止侧信道攻击非常有价值。
非目标
-
EdDSA 将只在 SunEC 提供程序中实现。在其他提供程序中实现此标准并非本 JEP 的目标。
-
EdDSA 的 API 和 SunEC 中的实现不会支持任意的域参数。EdDSA 的典型使用场景仅使用标准化的参数集,例如可以通过标识符指定的 Ed25519 和 Ed448,通常不需要支持任意曲线参数。EdDSA API 应该允许通过扩展来指定任意的域参数。此类扩展超出了本 JEP 的范围。
-
在本 JEP 完成后,将通过后续的增强功能完成 EdDSA 与 JSSE 在 TLS 1.3 中的集成。
成功指标
-
RFC 8032 中的所有测试向量均通过。
-
在所有平台上,吞吐量(根据现有密钥协商基准测试中每秒派生的密钥数来衡量)将与现有的 ECC 实现(具有类似安全强度)相比具有优势。
-
统计测试将表明签名操作的耗时不会随私钥的变化而变化。
动机
由于 EdDSA 相较于其他签名方案提高了安全性和性能,因此备受关注,并且已经在许多加密库(如 OpenSSL 和 BoringSSL)中得到支持。该签名方案是 TLS 1.3 的可选组件,但也是 TLS 1.3 中仅允许使用的三种签名方案之一。一些用户可能拥有 EdDSA 证书,并且有强烈的意愿使用 EdDSA。这些用户会非常欣赏无需依赖第三方库即可使用 EdDSA 的能力。开发 EdDSA 实现的另一个好处是,它使我们能够更轻松地开发和测试 TLS 1.3 对该算法的支持。
描述
点运算将使用 RFC 8032 中定义的双倍加法操作,并结合无分支条件赋值操作,以防止侧信道攻击。域运算将使用为 XDH 开发的模运算库(JEP 324)。在对 JVM 和硬件行为的一些合理假设下,组合实现不会将秘密泄露到时间侧信道和缓存侧信道中。
该 API 将重用为 XDH 开发的 NamedParameterSpec
类,以描述曲线域参数和 EdDSA 变体。将会开发用于 Edwards 曲线点、EdDSA 密钥和包含上下文信息的签名参数的新类和接口。
示例 API 用法:
// example: generate a key pair and sign
KeyPairGenerator kpg = KeyPairGenerator.getInstance("Ed25519");
KeyPair kp = kpg.generateKeyPair();
// algorithm is pure Ed25519
Signature sig = Signature.getInstance("Ed25519");
sig.initSign(kp.getPrivate());
sig.update(msg);
byte[] s = sig.sign();
// example: use KeyFactory to contruct a public key
KeyFactory kf = KeyFactory.getInstance("EdDSA");
boolean xOdd = ...
BigInteger y = ...
NamedParameterSpec paramSpec = new NamedParameterSpec("Ed25519");
EdECPublicKeySpec pubSpec = new EdECPublicKeySpec(paramSpec, new EdPoint(xOdd, y));
PublicKey pubKey = kf.generatePublic(pubSpec);
替代方案
-
原生实现(例如现有的 ECC 代码)可能会提供更好的性能。EdDSA 的性能应该与 XDH 相似,因此 Java 实现很可能已经足够快。
-
可以使用现有 ECC 代码中的点运算来实现此签名方案,但这种方法无法提供 RFC 8032 所具有的全部安全性和性能优势。
-
用户可以使用第三方库来获得对 EdDSA 的支持。在 JDK 中包含 EdDSA 实现的动机已在上面的“动机”部分中描述。
-
从技术上讲,可以使用现有的 ECC API 类来指定 EdDSA 密钥和参数,但这会带来密钥误用的重大风险。更多信息可参见 JDK-8166597。
测试
测试将包括 RFC 8032 中的测试向量,并增加对小亚群组和非规范值等极端情况的测试。
风险与假设
EdDSA 实现将使用为 XDH 开发的域算术库,因此存在同样的溢出风险和其他导致结果不正确的漏洞。通过继续分析和测试域算术库,可以降低这种风险。