Fehlermeldung
java.security.cert.CertPathValidatorException: Algorithm constraints check failed on keysize limits: RSA 768 bit key used with certificate: CN=api.example.com
Auch ausgegeben als
- Algorithm constraints check failed on keysize limits
- javax.net.ssl.SSLHandshakeException: (unsupported_certificate) PKIX path validation failed: java.security.cert.CertPathValidatorException: Algorithm constraints check failed on keysize limits
Schlüsseltyp, Schlüssellänge und Subject werden je Zertifikat eingesetzt. Die TLS-Schicht meldet den Fehler als „(unsupported_certificate) PKIX path validation failed: …“. Mit einem MD5-signierten Serverzertifikat scheiterte unser Test schon früher, mit handshake_failure vom Server, weil die JVM MD5-Signaturen gar nicht erst anbietet.
Java (PKIX validator) — jdk.certpath.disabledAlgorithms rejects a weak key or signature algorithm in the chain
Was der Fehler bedeutet
Java hat einen vertrauenswürdigen Pfad gebildet, aber ein Zertifikat darin verwendet einen Schlüssel (oder Signaturalgorithmus), den jdk.certpath.disabledAlgorithms verbietet, deshalb schlägt die Pfadvalidierung fehl. Die Meldung nennt den Algorithmus, die Schlüssellänge und das Subject des Zertifikats. Aktuelle JDKs lehnen in Zertifikatsketten RSA- und DSA-Schlüssel unter 1024 Bit, EC-Schlüssel unter 224 Bit sowie MD2-/MD5-Signaturen ab.
Warum der Fehler auftritt
Ein altes Zertifikat mit kurzem Schlüssel
häufigAlte Appliances, eingebettete Webserver und Testzertifikate, die mit RSA-Schlüsseln von 512 oder 768 Bit erzeugt wurden.
Ein mit MD5 signiertes Zertifikat in der Kette (oder SHA-1 unter einem mit dem JDK ausgelieferten Root-Zertifikat)
gelegentlichjdk.certpath.disabledAlgorithms führt außerdem MD2 und MD5 auf, dazu SHA-1 für TLS-Serverketten, die bei einer mit dem JDK ausgelieferten CA enden.
Ein JDK-Update hat die Beschränkungen verschärft
gelegentlichDie Beschränkungen werden in Sicherheitsupdates von Zeit zu Zeit verschärft; Zertifikate, die mit einem älteren Update noch durchgingen, können nach dem Upgrade scheitern.
So behebst du den Fehler
- 1.
Schwaches Zertifikat finden
Gib für jedes Zertifikat der ausgelieferten Kette die Schlüssellänge des öffentlichen Schlüssels und den Signaturalgorithmus aus.
bash # Key size and signature algorithm of every certificate the server sends openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts </dev/null 2>/dev/null \ | awk '/BEGIN CERT/{n++; f="c" n ".pem"} /BEGIN CERT/,/END CERT/{print > f}' for f in c*.pem; do openssl x509 -in "$f" -noout -subject -text | grep -E 'subject=|Public-Key|Signature Algorithm' | sort -u; done - 2.
Mit modernem Schlüssel neu ausstellen
ECDSA P-256 oder RSA ab 2048 Bit mit einer SHA-256-Signatur wird überall akzeptiert.
bash # Replace the weak key: ECDSA P-256 (or RSA 2048+) with a SHA-256 signature openssl req -new -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes -keyout server.key \ -subj "/CN=api.example.com" -addext "subjectAltName=DNS:api.example.com" -out server.csr - 3.
Beschränkungen des JDK nachlesen
jdk.certpath.disabledAlgorithms in java.security listet auf, was abgelehnt wird; lockern lässt sich die Liste, indem du die Security Properties überschreibst, doch damit sind wieder Schlüssel zugelassen, die sich brechen lassen.
bash # What this JDK rejects in certificate chains sed -n '/^jdk.certpath.disabledAlgorithms=/,/[^\\]$/p' "$JAVA_HOME/conf/security/java.security"