Mensagem de erro
java.security.InvalidKeyException: No installed provider supports this key: sun.security.rsa.RSAPublicKeyImpl
Também aparece como
- java.security.InvalidKeyException: No installed provider supports this key: sun.security.ec.ECPublicKeyImpl
- java.security.InvalidKeyException: No installed provider supports this key: sun.security.ec.ed.EdDSAPublicKeyImpl
O texto depois dos dois-pontos é a classe de implementação da chave (`sun.security.rsa.RSAPublicKeyImpl`, `sun.security.ec.ECPublicKeyImpl`, `sun.security.ec.ed.EdDSAPublicKeyImpl`, uma classe do Bouncy Castle…). Nos JDKs atuais, uma chave `null` falha antes, com “Key must not be null”.
Java (JDK) — Signature.initVerify / initSign, Cipher.init
O que significa
A JCA procurou um provedor cuja implementação do algoritmo solicitado aceitasse esse objeto de chave, e nenhum aceitou. Com os provedores padrão, isso quase sempre significa que a chave e o algoritmo pertencem a famílias diferentes — uma chave RSA passada para `SHA256withECDSA`, uma chave EC para `SHA256withRSA`, uma chave Ed25519 para ECDSA. O nome de classe no fim da mensagem mostra que tipo de chave realmente chegou.
Por que acontece
O algoritmo e o tipo da chave não correspondem
comumTípico de código JWT que deduz o algoritmo JCA a partir do cabeçalho do token, mas usa uma chave configurada estaticamente — depois que o emissor troca RS256 por ES256, ou quando tokens de dois emissores chegam ao mesmo verificador.
Uma chave Ed25519 ou X25519 tratada como chave EC
ocasionalChaves Ed25519 são chaves de curva elíptica, mas não são chaves ECDSA: exigem `Signature.getInstance("Ed25519")` (JDK 15+). Chaves X25519 servem apenas para acordo de chaves e não conseguem assinar nada.
Um objeto de chave de um provedor que não está registrado
ocasionalChaves criadas por um provedor HSM/PKCS#11 ou pelo Bouncy Castle só podem ser usadas por esse provedor. Se ele não estiver registrado (ou se você solicitar o algoritmo a outro provedor), nenhum provedor aceita a chave.
Como corrigir
- 1.
Deduzir o algoritmo e conferi-lo com a chave
Mapeie explicitamente os algoritmos JWS permitidos para nomes JCA e recuse combinações em que o tipo da chave não se encaixa, para que a falha seja um erro de política claro, e não um erro na busca de provedor.
java static Signature verifierFor(String jwsAlg, PublicKey key) throws GeneralSecurityException { String jca = switch (jwsAlg) { case "ES256" -> "SHA256withECDSAinP1363Format"; case "ES384" -> "SHA384withECDSAinP1363Format"; case "RS256" -> "SHA256withRSA"; case "PS256" -> "RSASSA-PSS"; default -> throw new GeneralSecurityException("algorithm not allowed: " + jwsAlg); }; boolean keyFits = jwsAlg.startsWith("ES") ? key instanceof java.security.interfaces.ECPublicKey : key instanceof java.security.interfaces.RSAPublicKey; if (!keyFits) throw new GeneralSecurityException(jwsAlg + " does not match a " + key.getAlgorithm() + " key"); Signature signature = Signature.getInstance(jca); if (jwsAlg.equals("PS256")) { signature.setParameter(new java.security.spec.PSSParameterSpec("SHA-256", "MGF1", java.security.spec.MGF1ParameterSpec.SHA256, 32, 1)); } signature.initVerify(key); return signature; }