Fehlermeldung
java.security.InvalidKeyException: No installed provider supports this key: sun.security.rsa.RSAPublicKeyImpl
Auch ausgegeben als
- 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
Der Text nach dem Doppelpunkt ist die Implementierungsklasse des Schlüssels (`sun.security.rsa.RSAPublicKeyImpl`, `sun.security.ec.ECPublicKeyImpl`, `sun.security.ec.ed.EdDSAPublicKeyImpl`, eine Klasse von Bouncy Castle …). Ein Schlüssel `null` scheitert auf aktuellen JDKs schon früher mit „Key must not be null“.
Java (JDK) — Signature.initVerify / initSign, Cipher.init
Was der Fehler bedeutet
JCA hat einen Provider gesucht, dessen Implementierung des angeforderten Algorithmus dieses Schlüsselobjekt akzeptiert, und keinen gefunden. Mit den Standard-Providern heißt das fast immer, dass Schlüssel und Algorithmus zu verschiedenen Familien gehören – ein RSA-Schlüssel für `SHA256withECDSA`, ein EC-Schlüssel für `SHA256withRSA`, ein Ed25519-Schlüssel für ECDSA. Der Klassenname am Ende verrät dir, welche Art von Schlüssel tatsächlich angekommen ist.
Warum der Fehler auftritt
Algorithmus und Schlüsseltyp passen nicht zusammen
häufigTypisch für JWT-Code, der den JCA-Algorithmus aus dem Header des Tokens ableitet, aber einen statisch konfigurierten Schlüssel verwendet – nachdem der Aussteller von RS256 auf ES256 umgestellt hat oder wenn Tokens von zwei Ausstellern bei derselben prüfenden Seite ankommen.
Ein Ed25519- oder X25519-Schlüssel wird als EC-Schlüssel behandelt
gelegentlichEd25519-Schlüssel sind Schlüssel auf Basis elliptischer Kurven, aber keine ECDSA-Schlüssel: Sie brauchen `Signature.getInstance("Ed25519")` (JDK 15+). X25519-Schlüssel dienen nur der Schlüsseleinigung und können überhaupt nicht signieren.
Ein Schlüsselobjekt von einem nicht registrierten Provider
gelegentlichSchlüssel, die ein HSM-/PKCS#11-Provider oder Bouncy Castle erzeugt hat, kann nur dieser Provider verwenden. Ist er nicht registriert (oder forderst du den Algorithmus bei einem anderen Provider an), akzeptiert kein Provider den Schlüssel.
So behebst du den Fehler
- 1.
Algorithmus ableiten und gegen den Schlüssel prüfen
Bilde die erlaubten JWS-Algorithmen explizit auf JCA-Namen ab und lehne Kombinationen ab, bei denen der Schlüsseltyp nicht passt – dann ist der Fehler ein klarer Richtlinienfehler statt eines Fehlers bei der Provider-Suche.
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; }