Message d’erreur
java.security.InvalidAlgorithmParameterException: Curve not supported: secp256k1 (1.3.132.0.10)
Également affiché sous la forme
- Legacy SunEC curve disabled
Exception levée par `KeyPairGenerator.initialize`, `KeyFactory.generatePublic/Private` (enveloppée dans `InvalidKeySpecException`) et `Signature.initVerify`, selon l’endroit où la courbe apparaît en premier. Le JDK 15 avait déjà désactivé ces courbes par défaut (JDK-8237219) avec le message « Legacy SunEC curve disabled », et `-Djdk.sunec.disableNative=false` les réactivait ; le JDK 14 et les versions antérieures les prenaient en charge.
Java (JDK 16+) — KeyPairGenerator / KeyFactory / Signature with the SunEC provider
Ce que cela signifie
Le JDK connaît le nom secp256k1 (la courbe utilisée par Bitcoin et Ethereum) et le résout même vers son OID 1.3.132.0.10, mais son fournisseur intégré SunEC ne l’implémente plus. Le JDK 16 a supprimé les courbes historiques en même temps que la bibliothèque EC native (note de version « Removal of Legacy Elliptic Curves », JDK-8235710) et n’a conservé que les courbes disposant d’implémentations modernes : P-256, P-384, P-521, X25519/X448 et Ed25519/Ed448. Un code qui fonctionnait sous Java 8 ou 11 échoue ici après une mise à niveau.
Pourquoi cela se produit
Exécution sur le JDK 16 ou une version plus récente
fréquenteLa liste des courbes de SunEC s’est réduite dans le JDK 16. La mise à niveau de l’environnement d’exécution d’un service lié à la blockchain en est le déclencheur le plus fréquent.
JWT ES256K ou JWK secp256k1
occasionnelleLes bibliothèques JOSE qui délèguent à JCA (par exemple Nimbus) ont besoin d’un fournisseur qui prend en charge secp256k1 pour `ES256K` (RFC 8812).
Code copié d’un exemple antérieur à 2021
occasionnelleLes exemples qui utilisent `ECGenParameterSpec("secp256k1")` avec le fournisseur par défaut sont antérieurs à la suppression.
Comment corriger l’erreur
- 1.
Utiliser le fournisseur Bouncy Castle
Bouncy Castle implémente secp256k1 en Java pur. Enregistrez-le et demandez-le explicitement avec `"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.
Pour Ethereum, utiliser une bibliothèque conçue pour cela
web3j et les bibliothèques similaires gèrent pour vous secp256k1, les identifiants de récupération et les préfixes EIP-191, ce que JCA seul ne fait pas.
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);