Tengo un certificado de entidad final/servidor que tiene un certificado intermedio y raíz. Cuando accedo cat
al certificado de entidad final, solo veo una etiqueta BEGIN
y END
. Es el único certificado de entidad final.
¿Hay alguna manera de poder ver el contenido del certificado raíz e intermedio? Sólo necesito el contenido BEGIN
y END
la etiqueta.
En Windows puedo ver la cadena de certificados completa en la "Ruta de certificación". A continuación se muestra el ejemplo del certificado de Stack Exchange.
Desde allí puedo realizar unVer Certificadoy exportarlos. Puedo hacer eso tanto para el root como para el intermedio en Windows. Estoy buscando este mismo método en Linux.
Respuesta1
Desde un sitio web, puedes hacer:
openssl s_client -showcerts -verify 5 -connect stackexchange.com:443 < /dev/null
Eso mostrará la cadena de certificados y todos los certificados que presentó el servidor.
Ahora, si guardo esos dos certificados en archivos, puedo usar openssl verify
:
$ openssl verify -show_chain -untrusted dc-sha2.crt se.crt
se.crt: OK
Chain:
depth=0: C = US, ST = NY, L = New York, O = "Stack Exchange, Inc.", CN = *.stackexchange.com (untrusted)
depth=1: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA (untrusted)
depth=2: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance EV Root CA
La -untrusted
opción se utiliza para otorgar el(los) certificado(s) intermedio(s); se.crt
es el certificado a verificar. El resultado de profundidad = 2 provino del almacén de CA confiable del sistema.
Si no tiene los certificados intermedios, no podrá realizar la verificación. Así es como funciona X.509.
Dependiendo del certificado, puede contener un URI para obtener el intermedio. A modo de ejemplo, openssl x509 -in se.crt -noout -text
contiene:
Authority Information Access:
OCSP - URI:http://ocsp.digicert.com
CA Issuers - URI:http://cacerts.digicert.com/DigiCertSHA2HighAssuranceServerCA.crt
Ese URI de "Emisores de CA" apunta al certificado intermedio (en formato DER, por lo que debe usarlo openssl x509 -inform der -in DigiCertSHA2HighAssuranceServerCA.crt -out DigiCertSHA2HighAssuranceServerCA.pem
para convertirlo para su uso posterior en OpenSSL).
Si ejecuta, openssl x509 -in /tmp/DigiCertSHA2HighAssuranceServerCA.pem -noout -issuer_hash
obtendrá 244b5494
, que puede buscar en el almacén de CA raíz del sistema en /etc/ssl/certs/244b5494.0
(simplemente agréguelo .0
al nombre).
No creo que exista un comando OpenSSL sencillo y agradable que pueda hacer todo eso por usted.
Respuesta2
tl;dr: magia de bash de una sola línea para volcar todos los certificados de la cadena
openssl s_client -showcerts -verify 5 -connect wikipedia.org:443 < /dev/null |
awk '/BEGIN CERTIFICATE/,/END CERTIFICATE/{ if(/BEGIN CERTIFICATE/){a++}; out="cert"a".pem"; print >out}'
for cert in *.pem; do
newname=$(openssl x509 -noout -subject -in $cert | sed -nE 's/.*CN ?= ?(.*)/\1/; s/[ ,.*]/_/g; s/__/_/g; s/_-_/-/; s/^_//g;p' | tr '[:upper:]' '[:lower:]').pem
echo "${newname}"; mv "${cert}" "${newname}"
done
Explicación en 2 pasos
Para volcar todos los certificados de la cadena al directorio actual como cert${chain_number}.pem
:
openssl s_client -showcerts -verify 5 -connect your_host:443 < /dev/null |
awk '/BEGIN CERTIFICATE/,/END CERTIFICATE/{ if(/BEGIN CERTIFICATE/){a++}; out="cert"a".pem"; print >out}'
El bonus-track para cambiarles el nombre a su nombre común:
for cert in *.pem; do
newname=$(openssl x509 -noout -subject -in $cert | sed -nE 's/.*CN ?= ?(.*)/\1/; s/[ ,.*]/_/g; s/__/_/g; s/_-_/-/; s/^_//g;p' | tr '[:upper:]' '[:lower:]').pem
mv $cert $newname
done
Respuesta3
Descubrí que con la opción -verify 5
openssl se profundiza en la cadena mostrando todos los certificados, incluso los que no están incluidos en la implementación de su certificado.
Si realmente desea comprender qué cadena se proporciona con su certificado, debe ejecutar:
openssl s_client -showcerts -partial_chain -connect YOUR_ENDPOINT:443 < /dev/null |less
Respuesta4
Lo anterior no funcionó para mí cuando estaba usando un certificado comodín gratuito de Lets Encrypt.
Para ser más específico:
tengo un clúster de Kubernetes + controlador de ingreso que está configurado usando un certificado comodín gratuito de Lets Encrypt para *.mydomain.dev, aloja los siguientes 2 nombres de dominio:
- grafana.midominio.dev
- prometheus.midominio.dev
Tuve que agregar el indicador -servername siguiente en este sitio:https://community.letsencrypt.org/t/where-can-i-download-the-trusted-root-ca-certificates-for-lets-encrypt/33241/2
export DOMAIN=grafana.mydomain.dev
openssl s_client -showcerts -verify 5 -connect $DOMAIN:443 -servername $DOMAIN < /dev/null 2> /dev/null | awk '/BEGIN/,/END/{ if(/BEGIN/){a++}; print}'
También modifiqué la cadena para que me proporcione el certificado completo + intermedio + raíz a la salida estándar y oculte el ruido estándar.
En realidad... Al realizar las pruebas descubrí que esto no me da la CA...
openssl s_client -showcerts -verify 5 -connect letsencrypt.org:443 < /dev/null 2> /dev/null | awk '/BEGIN/,/END/{ if(/BEGIN/){a++}; print}'
curl https://letsencrypt.org/certs/isrgrootx1.pem
Da un valor diferente (y cuando se prueban algunas cosas, este es el valor que funciona).