Using openssl to get the certificate from a server

952,538

Solution 1

It turns out there is more complexity here: I needed to provide many more details to get this rolling. I think its something to do with the fact that its a connection that needs client authentication, and the hankshake needed more info to continue to the stage where the certificates were dumped.

Here is my working command:

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

Hopefully this is a nudge in the right direction for anyone who could do with some more info.

Solution 2

With SNI

If the remote server is using SNI (that is, sharing multiple SSL hosts on a single IP address) you will need to send the correct hostname in order to get the right certificate.

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

Without SNI

If the remote server is not using SNI, then you can skip -servername parameter:

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


To view the full details of a site's cert you can use this chain of commands as well:

$ echo | \
    openssl s_client -servername www.example.com -connect www.example.com:443 2>/dev/null | \
    openssl x509 -text

Solution 3

A one-liner to extract the certificate from a remote server in PEM format, this time using sed:

openssl s_client -connect www.google.com:443 2>/dev/null </dev/null |  sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'

Solution 4

While I agree with Ari's answer (and upvoted it :), I needed to do an extra step to get it to work with Java on Windows (where it needed to be deployed):

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

Before adding the openssl x509 -outform DER conversion, I was getting an error from keytool on Windows complaining about the certificate's format. Importing the .der file worked fine.

Solution 5

The easiest command line for this, which includes the PEM output to add it to the keystore, as well as a human readable output and also supports SNI, which is important if you are working with an HTTP server is:

openssl s_client -servername example.com -connect example.com:443 \
    </dev/null 2>/dev/null | openssl x509 -text

The -servername option is to enable SNI support and the openssl x509 -text prints the certificate in human readable format.

Share:
952,538
nasty pasty
Author by

nasty pasty

I always respond, and make sure the answer exists - whether from someone else's answer or my own.

Updated on July 08, 2022

Comments

  • nasty pasty
    nasty pasty almost 2 years

    I am trying to get the certificate of a remote server, which I can then use to add to my keystore and use within my Java application.

    A senior dev (who is on holidays :( ) informed me I can run this:

    openssl s_client -connect host.host:9999
    

    to get a raw certificate dumped out, which I can then copy and export. I receive the following output:

    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:
    

    I have also tried it with this option:

    -showcerts
    

    and this one (running on Debian mind you):

    -CApath /etc/ssl/certs/
    

    But I get the same error.

    This source says I can use that CApath flag but it doesn't seem to help. I tried multiple paths to no avail.

    Please let me know where I'm going wrong.