¿Cómo extraer la CA raíz y la CA subordinada de una cadena de certificados en Linux?

25

Tengo un certificado de entidad final / servidor que tiene un certificado intermedio y raíz. Cuando caten el certificado de entidad final, sólo veo un único BEGINy ENDetiqueta. Es el único certificado de entidad final.

¿Hay alguna forma de ver el contenido del certificado intermedio y raíz? Solo necesito el contenido BEGINy la ENDetiqueta.

En Windows puedo ver la cadena completa de cert desde la "Ruta de certificación". A continuación se muestra el ejemplo del certificado de Stack Exchange.

ingrese la descripción de la imagen aquí

A partir de ahí puedo realizar un certificado de vista y exportarlos. Puedo hacer eso para root e intermedio en Windows. Estoy buscando este mismo método en Linux.

ingrese la descripción de la imagen aquí

Anirban Nag 'tintinmj'
fuente
Díganos quién le emitió ese certificado.
Rui F Ribeiro
@RuiFRibeiro Digamos que cualquiera ... Quiero ver la cadena de certificados para stackexchange con solo el certificado primario en la mano.
Anirban Nag 'tintinmj'

Respuestas:

25

Desde un sitio web, puede 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 -untrustedopción se usa para dar los certificados intermedios; se.crtes el certificado a verificar. El resultado de la profundidad = 2 provino del almacén de CA de confianza del sistema.

Si no tiene los certificados intermedios, no puede realizar la verificación. Así es como funciona X.509.

Dependiendo del certificado, puede contener un URI para obtener el intermedio. Como ejemplo, openssl x509 -in se.crt -noout -textcontiene:

        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.pempara convertirlo para que OpenSSL lo use).

Si ejecuta openssl x509 -in /tmp/DigiCertSHA2HighAssuranceServerCA.pem -noout -issuer_hash, obtiene 244b5494, que puede buscar en la tienda de CA raíz del sistema en /etc/ssl/certs/244b5494.0(solo agregue .0el nombre).

No creo que haya un comando OpenSSL agradable y fácil para hacer todo eso por usted.

derobert
fuente
Ese es el problema principal. No tengo la URL conmigo. Solo tengo el archivo del certificado. Y necesito el contenido encriptado entre BEGINy la ENDetiqueta (que obtendrás después catde crear el archivo .crt.)
Anirban Nag 'tintinmj'
@ AnirbanNag'tintinmj 'Si solo está buscando decodificar el certificado, intenteopenssl x509 -in file.crt -noout -text
derobert
Quiero el contenido de intermedio en el certificado raíz que está entre la etiqueta BEGINy END.
Anirban Nag 'tintinmj'
O si puede dar un comando que extraiga el certificado intermedio y el raíz del certificado primario y lo guarde en un archivo ... también puedo vivir con eso.
Anirban Nag 'tintinmj'
@ AnirbanNag'tintinmj 'Si no aparece con el openssl x509comando, no creo que el certificado intermedio esté allí. (A menos que tenga algún error de openssl x509).
derobert
12

tl; dr - one liner bash magic para volcar todos los certificados de la cadena

openssl s_client -showcerts -verify 5 -connect de.wikipedia.org:443 < /dev/null | awk '/BEGIN/,/END/{ if(/BEGIN/){a++}; out="cert"a".crt"; print >out}' && for cert in *.crt; do newname=$(openssl x509 -noout -subject -in $cert | sed -n 's/^.*CN=\(.*\)$/\1/; s/[ ,.*]/_/g; s/__/_/g; s/^_//g;p').pem; 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/,/END/{ if(/BEGIN/){a++}; out="cert"a".pem"; print >out}' 

bonus-track para cambiarles el nombre a su nombre común:

for cert in *.pem; do newname=$(openssl x509 -noout -subject -in $cert | sed -n 's/^.*CN=\(.*\)$/\1/; s/[ ,.*]/_/g; s/__/_/g; s/^_//g;p').pem; mv $cert $newname; done
estani
fuente
¿Hay alguna razón para elegir ".pem" versus ".crt" como la extensión ya que solo los renombra, no cambia el formato?
Capitán Man
No en realidad no. ".pem" es el formato (base64 del DER) ".crt" significa que es un certificado pero no dice nada sobre la codificación. Estaba a punto de hacerlo más coherente y nombrar a todos los pem ... Pero creo que es más fácil de leer en un solo trazo para comprender dónde se descarga el certificado (crt) y terminar lo que normalmente uso en el mundo Linux (pem) . Espero que esto aclare un poco las cosas ...
estani
1
Sí, lo sé, me doy cuenta de que PEM es un formato, pero a menudo veo crt y no estaba seguro de si era un formato. Esto realmente ayuda a explicar por qué veo que "crt" se usa con tanta frecuencia. Gracias :)
Capitán Man
Esto parece funcionar solo si ya confía en la fuente. Estoy tratando de descargar una CA personalizada, pero solo está descargando el primer certificado, no la cadena.
mjaggard
@mjaggard extraño ya que lo usé exactamente para ese caso. Dicho esto, es posible que el servidor no envíe la CA raíz en absoluto, si echas un vistazo a mi ejemplo, solía descargar 3 certificados ahora solo está descargando 2. Supongo que el servidor wikipedia no está enviando la raíz (realmente no hay punto, si no lo tienes, no vas a confiar de todos modos ...). Estoy bastante seguro de que no era el caso antes.
estani