Mensagem de erro
java.security.InvalidAlgorithmParameterException: Curve not supported: secp256k1 (1.3.132.0.10)
Também aparece como
- Legacy SunEC curve disabled
A exceção é lançada por `KeyPairGenerator.initialize`, `KeyFactory.generatePublic/Private` (encapsulada em `InvalidKeySpecException`) e `Signature.initVerify`, conforme o ponto em que a curva aparece primeiro. O JDK 15 já tinha desativado essas curvas por padrão (JDK-8237219), com a mensagem “Legacy SunEC curve disabled”, e era possível reativá-las com `-Djdk.sunec.disableNative=false`; o JDK 14 e os anteriores tinham suporte a elas.
Java (JDK 16+) — KeyPairGenerator / KeyFactory / Signature with the SunEC provider
O que significa
O JDK conhece o nome secp256k1 (a curva usada pelo Bitcoin e pelo Ethereum) — chega a resolvê-lo para o OID 1.3.132.0.10 —, mas o provedor SunEC embutido não a implementa mais. O JDK 16 removeu as curvas legadas junto com a biblioteca EC nativa (nota de versão “Removal of Legacy Elliptic Curves”, JDK-8235710) e manteve só as curvas com implementações modernas: P-256, P-384, P-521, X25519/X448 e Ed25519/Ed448. Código que funcionava no Java 8 ou 11 falha aqui depois de uma atualização.
Por que acontece
A aplicação roda no JDK 16 ou mais recente
comumA lista de curvas do SunEC encolheu no JDK 16. Atualizar o runtime de um serviço ligado a blockchain é o gatilho mais comum.
JWTs ES256K ou JWKs secp256k1
ocasionalBibliotecas JOSE que delegam à JCA (por exemplo, a Nimbus) precisam de um provedor com secp256k1 para `ES256K` (RFC 8812).
Código copiado de um exemplo anterior a 2021
ocasionalExemplos que usam `ECGenParameterSpec("secp256k1")` com o provedor padrão são anteriores à remoção.
Como corrigir
- 1.
Usar o provedor Bouncy Castle
O Bouncy Castle implementa a secp256k1 em Java puro. Registre o provedor e solicite-o explicitamente com `"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.
Para trabalhar com Ethereum, usar uma biblioteca feita para isso
O web3j e bibliotecas semelhantes cuidam da secp256k1, dos IDs de recuperação e dos prefixos EIP-191 por você, o que a JCA pura não faz.
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);