Usando openssl para obtener el certificado de un servidor

Resuelto nasty pasty asked hace 13 años • 15 respuestas

Estoy intentando obtener el certificado de un servidor remoto, que luego puedo usar para agregarlo a mi almacén de claves y usarlo dentro de mi aplicación Java.

Un desarrollador senior (que está de vacaciones :() me informó que puedo ejecutar esto:

openssl s_client -connect host.host:9999

para obtener un certificado sin formato, que luego puedo copiar y exportar. Recibo el siguiente resultado:

depth=1 /C=NZ/ST=Test State or Province/O=Organization Name/OU=Organizational Unit Name/CN=Test CA
verify error:num=19:self signed certificate in certificate chain
verify return:0
23177:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:s3_pkt.c:1086:SSL alert number 40
23177:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:188:

También lo he probado con esta opción:

-showcerts

y este (ejecutándose en Debian, claro está):

-CApath /etc/ssl/certs/

Pero me sale el mismo error.

Esta fuente dice que puedo usar ese indicador CApath pero no parece ayudar. Intenté varios caminos sin éxito.

Por favor, déjame saber dónde me estoy equivocando.

nasty pasty avatar Oct 25 '11 14:10 nasty pasty
Aceptado

Con SNI

Si el servidor remoto utiliza SNI (es decir, comparte varios hosts SSL en una única dirección IP), deberá enviar el nombre de host correcto para obtener el certificado correcto.

openssl s_client -showcerts -servername www.example.com -connect www.example.com:443 </dev/null

Si recibe un error similar a xxx:error:xxx:BIO routines:BIO_lookup_ex:system lib:crypto/bio/bio_addr.c:758:nodename nor servname provided, or not known connect:errno=0, ejecute el mismo comando sin ya wwwque es posible que el dominio no lo admita.

También puede estar Secure Renegotiation IS NOT supporteddetrás de un firewall corporativo, en cuyo caso, una solución temporal (pero peligrosa) es el -legacy_renegotiationparámetro que se puede agregar al comando anterior.

Sin SNI

Si el servidor remoto no utiliza SNI, puede omitir -servernameel parámetro:

openssl s_client -showcerts -connect www.example.com:443 </dev/null

Para ver los detalles completos del certificado de un sitio, también puede utilizar esta cadena de comandos:

$ echo | \
    openssl s_client -servername www.example.com -connect www.example.com:443 2>/dev/null | \
    openssl x509 -text
Ari Maniatis avatar Oct 25 '2011 07:10 Ari Maniatis

Una sola línea para extraer el certificado de un servidor remoto en formato PEM, esta vez usando sed:

openssl s_client -connect www.google.com:443 2>/dev/null </dev/null |  sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'
André Fernandes avatar Sep 28 '2018 10:09 André Fernandes

Si bien estoy de acuerdo con la respuesta de Ari (y la voté :), necesitaba hacer un paso adicional para que funcionara con Java en Windows (donde era necesario implementarlo):

openssl s_client -showcerts -connect www.example.com:443 < /dev/null | openssl x509 -outform DER > derp.der

Antes de agregar la openssl x509 -outform DERconversión, recibí un error de keytool en Windows quejándose del formato del certificado. Importar el archivo .der funcionó bien.

David Jaquay avatar May 28 '2013 16:05 David Jaquay

Resulta que aquí hay más complejidad: necesitaba proporcionar muchos más detalles para que esto funcionara. Creo que tiene algo que ver con el hecho de que es una conexión que necesita autenticación del cliente y el hankshake necesitaba más información para continuar hasta la etapa en la que se descartaron los certificados.

Aquí está mi comando de trabajo:

openssl s_client -connect host:port -key our_private_key.pem -showcerts \
                 -cert our_server-signed_cert.pem

Con suerte, esto es un empujón en la dirección correcta para cualquiera a quien le vendría bien más información.

nasty pasty avatar Oct 27 '2011 01:10 nasty pasty