Mensaje de error
verify error:num=21:unable to verify the first certificate
También se muestra como
- Verify return code: 21 (unable to verify the first certificate)
openssl s_client lo imprime como «verify error:num=21:…» y «Verify return code: 21 (…)». Node.js notifica la misma situación como UNABLE_TO_VERIFY_LEAF_SIGNATURE («unable to verify the first certificate»).
OpenSSL CLI (openssl s_client) — X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE
Qué significa
Error 21 de OpenSSL (X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE): la cadena consta de un único certificado, el propio del servidor, y no se encontró su emisor, así que ni siquiera se puede comprobar la firma del certificado hoja. s_client suele imprimir justo antes el error 20 para la profundidad 0. La solución está casi siempre en el servidor: debe enviar su certificado intermedio.
Por qué ocurre
El servidor está configurado solo con el certificado hoja
frecuentecert.pem en lugar de fullchain.pem, un certificado pegado en un balanceador de carga sin su cadena o una entrada de un keystore de Java importada sin la CA emisora.
La cadena está configurada, pero no se envía
ocasionalAlgunos servidores necesitan la cadena en una directiva o un campo aparte (SSLCertificateChainFile en Apache antiguo, el cuadro de la cadena en un balanceador de carga en la nube); un bundle en el lugar equivocado se ignora sin avisar.
El servidor envía un intermedio que no emitió el certificado hoja
ocasionalCuando una CA cambia de intermedios, un archivo de cadena antiguo envía un certificado que no es el emisor del certificado hoja, y OpenSSL no puede usarlo.
Cómo solucionarlo
- 1.
Comprobar qué envía el servidor
Un único certificado cuyo emisor (i:) es una CA intermedia confirma el problema.
bash openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts </dev/null 2>/dev/null \ | grep -E '^ *[0-9]+ s:|^ *i:' - 2.
Servir el certificado hoja + los intermedios
Concatena en orden el certificado hoja y el intermedio o los intermedios emisores, y configura el servidor con ese archivo; imprime el bundle para comprobar el orden.
bash # Build the file the server should use: leaf, then intermediates (issuer of each previous one) cat server.pem intermediate.pem > fullchain.pem openssl crl2pkcs7 -nocrl -certfile fullchain.pem | openssl pkcs7 -print_certs -noout # check the order - 3.
Encontrar el intermedio correcto
La extensión Authority Information Access del certificado hoja indica la URL del certificado de su emisor; descárgalo, conviértelo a PEM si hace falta y añádelo al archivo de la cadena.
bash # Where to download the missing intermediate: the leaf's Authority Information Access URL openssl x509 -in server.pem -noout -ext authorityInfoAccess curl -sS -o intermediate.der http://ca.example.com/issuing-ca.crt openssl x509 -inform der -in intermediate.der -out intermediate.pem