跳到主要内容
ecdsa.com
Java (JDK 16+)Java

错误信息

java.security.InvalidAlgorithmParameterException: Curve not supported: secp256k1 (1.3.132.0.10)

也可能输出为

  • Legacy SunEC curve disabled

根据曲线最先出现的位置,由 `KeyPairGenerator.initialize`、`KeyFactory.generatePublic/Private`(包装在 `InvalidKeySpecException` 中)或 `Signature.initVerify` 抛出。JDK 15 已默认禁用这些曲线(JDK-8237219),消息为“Legacy SunEC curve disabled”,可以用 `-Djdk.sunec.disableNative=false` 重新启用;JDK 14 及更早版本支持这些曲线。

Java (JDK 16+) — KeyPairGenerator / KeyFactory / Signature with the SunEC provider

含义

JDK 认得 secp256k1 这个名称(比特币和以太坊使用的曲线)——甚至能把它解析为 OID 1.3.132.0.10——但内置的 SunEC 提供程序已经不再实现它。JDK 16 移除了旧式曲线以及原生 EC 库(版本说明“Removal of Legacy Elliptic Curves”,JDK-8235710),只保留了有现代实现的曲线:P-256、P-384、P-521、X25519/X448 和 Ed25519/Ed448。在 Java 8 或 11 上能运行的代码,升级后会在这里失败。

原因

修复方法

  1. 1.

    使用 Bouncy Castle 提供程序

    Bouncy Castle 用纯 Java 实现了 secp256k1。注册它,并用 `"BC"` 显式指定它。

    java
    import java.security.*;
    import java.security.spec.ECGenParameterSpec;
    import org.bouncycastle.jce.provider.BouncyCastleProvider;
    
    Security.addProvider(new BouncyCastleProvider());
    KeyPairGenerator generator = KeyPairGenerator.getInstance("EC", "BC");
    generator.initialize(new ECGenParameterSpec("secp256k1"));
    KeyPair pair = generator.generateKeyPair();
    
    Signature signature = Signature.getInstance("SHA256withECDSA", "BC");
  2. 2.

    以太坊开发使用专门的库

    web3j 等库会替你处理 secp256k1、恢复 ID 和 EIP-191 前缀,而纯 JCA 做不到这些。

    java
    // Ethereum signing/recovery: web3j implements secp256k1 itself (on top of Bouncy Castle).
    org.web3j.crypto.ECKeyPair keyPair = org.web3j.crypto.Keys.createEcKeyPair();
    org.web3j.crypto.Sign.SignatureData sig = org.web3j.crypto.Sign.signPrefixedMessage(message, keyPair);

相关错误

浏览完整的签名错误库