本文へスキップ
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;
    }

関連するエラー

署名エラーデータベースをすべて見る