Pular para o conteúdo
ecdsa.com
Java (JDK)Java

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

Como corrigir

  1. 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;
    }

Erros relacionados

Ver toda a base de erros de assinatura