Fehlermeldung
java.security.InvalidAlgorithmParameterException: Curve not supported: secp256k1 (1.3.132.0.10)
Auch ausgegeben als
- Legacy SunEC curve disabled
Wird von `KeyPairGenerator.initialize`, `KeyFactory.generatePublic/Private` (verpackt in `InvalidKeySpecException`) und `Signature.initVerify` geworfen, je nachdem, wo die Kurve zuerst auftaucht. JDK 15 hatte diese Kurven bereits standardmäßig deaktiviert (JDK-8237219), mit der Meldung „Legacy SunEC curve disabled“; `-Djdk.sunec.disableNative=false` aktivierte sie wieder. JDK 14 und älter unterstützten sie.
Java (JDK 16+) — KeyPairGenerator / KeyFactory / Signature with the SunEC provider
Was der Fehler bedeutet
Das JDK kennt den Namen secp256k1 (die Kurve, die Bitcoin und Ethereum verwenden) – es löst ihn sogar in die OID 1.3.132.0.10 auf –, aber der eingebaute Provider SunEC implementiert die Kurve nicht mehr. JDK 16 hat die Legacy-Kurven zusammen mit der nativen EC-Bibliothek entfernt (Release Note „Removal of Legacy Elliptic Curves“, JDK-8235710) und nur Kurven mit modernen Implementierungen behalten: P-256, P-384, P-521, X25519/X448 und Ed25519/Ed448. Code, der unter Java 8 oder 11 funktionierte, scheitert nach einem Upgrade an dieser Stelle.
Warum der Fehler auftritt
Die Anwendung läuft unter JDK 16 oder neuer
häufigDie Kurvenliste von SunEC ist in JDK 16 geschrumpft. Der häufigste Auslöser ist ein Upgrade der Laufzeitumgebung eines Blockchain-Dienstes.
ES256K-JWTs oder secp256k1-JWKs
gelegentlichJOSE-Bibliotheken, die an JCA delegieren (zum Beispiel Nimbus), brauchen für `ES256K` (RFC 8812) einen Provider mit secp256k1.
Aus einem Beispiel von vor 2021 kopierter Code
gelegentlichBeispiele, die `ECGenParameterSpec("secp256k1")` mit dem Standard-Provider verwenden, stammen aus der Zeit vor der Entfernung.
So behebst du den Fehler
- 1.
Provider Bouncy Castle verwenden
Bouncy Castle implementiert secp256k1 in reinem Java. Registriere den Provider und fordere ihn explizit mit `"BC"` an.
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.
Für Ethereum eine Bibliothek verwenden, die dafür gebaut ist
web3j und ähnliche Bibliotheken kümmern sich für dich um secp256k1, Recovery-IDs und EIP-191-Präfixe – das reine JCA tut das nicht.
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);