Mensaje de error
java.security.cert.CertPathValidatorException: Algorithm constraints check failed on keysize limits: RSA 768 bit key used with certificate: CN=api.example.com
También se muestra como
- 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
El tipo y el tamaño de la clave y el sujeto se rellenan para cada certificado. La capa TLS lo comunica como «(unsupported_certificate) PKIX path validation failed: …». Con un certificado de servidor firmado con MD5, nuestra prueba falló antes, con un handshake_failure del servidor, porque la JVM ni siquiera ofrece firmas MD5.
Java (PKIX validator) — jdk.certpath.disabledAlgorithms rejects a weak key or signature algorithm in the chain
Qué significa
Java construyó una ruta de confianza, pero uno de sus certificados usa una clave (o un algoritmo de firma) que jdk.certpath.disabledAlgorithms prohíbe, así que la validación de la ruta falla. El mensaje indica el algoritmo, el tamaño de clave y el sujeto del certificado. Los JDK actuales rechazan en las cadenas de certificados las claves RSA y DSA de menos de 1024 bits, las claves EC de menos de 224 bits y las firmas MD2/MD5.
Por qué ocurre
Un certificado heredado con una clave pequeña
frecuenteDispositivos dedicados antiguos, servidores web integrados y certificados de prueba generados con claves RSA de 512 o 768 bits.
Un certificado de la cadena firmado con MD5 (o con SHA-1 bajo una raíz incluida en el JDK)
ocasionaljdk.certpath.disabledAlgorithms también incluye MD2, MD5 y SHA-1 para las cadenas de servidores TLS que terminan en una CA incluida en el JDK.
Una actualización del JDK endureció las restricciones
ocasionalLas restricciones se endurecen de vez en cuando en las actualizaciones de seguridad; los certificados que se aceptaban con una actualización anterior pueden fallar después de actualizar.
Cómo solucionarlo
- 1.
Encontrar el certificado débil
Imprime el tamaño de la clave pública y el algoritmo de firma de cada certificado de la cadena que sirve el servidor.
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.
Volver a emitir el certificado con una clave moderna
ECDSA P-256 o RSA de 2048 bits o más con firma SHA-256 se acepta en todas partes.
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.
Leer las restricciones del JDK
jdk.certpath.disabledAlgorithms, en java.security, enumera lo que se rechaza; se puede relajar sobrescribiendo las propiedades de seguridad, pero así se vuelven a admitir claves que se pueden romper.
bash # What this JDK rejects in certificate chains sed -n '/^jdk.certpath.disabledAlgorithms=/,/[^\\]$/p' "$JAVA_HOME/conf/security/java.security"