Перейти к содержимому
ecdsa.com
Java (JDK)Java

Сообщение об ошибке

java.security.InvalidKeyException: No installed provider supports this key: sun.security.rsa.RSAPublicKeyImpl

Также выводится как

  • 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

Текст после двоеточия — класс реализации ключа (`sun.security.rsa.RSAPublicKeyImpl`, `sun.security.ec.ECPublicKeyImpl`, `sun.security.ec.ed.EdDSAPublicKeyImpl`, класс Bouncy Castle…). В современных JDK ключ `null` вызывает ошибку раньше, с сообщением «Key must not be null».

Java (JDK) — Signature.initVerify / initSign, Cipher.init

Что это означает

Среди провайдеров JCA не нашлось ни одного, чья реализация запрошенного алгоритма принимает этот объект ключа. С провайдерами по умолчанию это почти всегда означает, что ключ и алгоритм из разных семейств: ключ RSA передан в `SHA256withECDSA`, ключ EC — в `SHA256withRSA`, ключ Ed25519 — в ECDSA. Имя класса в конце показывает, какой ключ пришёл на самом деле.

Почему это происходит

Как исправить

  1. 1.

    Определяйте алгоритм и сверяйте его с ключом

    Явно сопоставьте разрешённые алгоритмы JWS с именами JCA и отклоняйте сочетания, в которых тип ключа не подходит: тогда сбой будет понятной ошибкой политики, а не ошибкой поиска провайдера.

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

Связанные ошибки

Открыть всю базу ошибок подписей