How to dump the Subject Alternative Name (SAN) from an SSL certificate file

I know that I can dump the entire information from a PEM certificate file with this command:

openssl x509 -in certfile -noout -text

And I've already found another direct parameter to show me only the expiry date of a certificate:

openssl x509 -in certfile -noout -enddate

But is there also a shortcut to get only the alternative names? Like when a certificate can be used for example.com as well as In the full dump, it's here:

Certificate: Data: X509v3 extensions: X509v3 Subject Alternative Name: DNS: DNS:example.com

I'd just like to save me the hassle to parse this output and get the domain names only. Is that possible? Otherwise, what would be best practices to parse this output? What can be assumed, what may change? Could I use a regexp like X509v3 Subject Alternative Name:\s*DNS:(\S+)(?:, DNS:(\S+))*?

5 Answers

Here's what I would do to make it a little more readable:

for i in $(openssl x509 -in certfile -noout -text | grep -A1 'Subject Alternative Name' | tail -n1 | tr -d ','); { echo $i | cut -f2 -d:; }

This gets you a long list format, assuming the same input as the sample above, something like this:

*.google.com
*.android.com
*.appengine.google.com
*.cloud.google.com
...

Where the raw output of the line would have been:

DNS:*.google.com, DNS:*.android.com, DNS:*.appengine.google.com, DNS:*.cloud.google.com

Of course you have to choose the right format for your list. For instance, that actual Google list is quite long and difficult to consume. If you're looking for something specific breaking the entries on to each line allows you to grep for the entry you're looking for and remove all the other information.

So this (notice the grep at the end) ...

for i in $(openssl x509 -in certfile -noout -text | grep -A1 'Subject Alternative Name' | tail -n1 | tr -d ','); { echo $i | cut -f2 -d:; } | grep google.com

Results in...

*.google.com

I find this method works reasonably well and is easy to remember since it's just a grep DNS:.

$ openssl x509 -noout -text -in cert.pem | grep DNS: DNS:localhost, DNS:someserver1.somedom.local, DNS:someserver2.somedom.com, DNS:someserver3

Since there can be many entries, I simply select the next line and clean it up using awk and tr

openssl x509 -noout -text -in certfile | awk '/X509v3 Subject Alternative Name/ {getline;gsub(/ /, "", $0); print}' | tr -d "DNS:"

Here is what you get with google.com

*.google.com,*.android.com,*.appengine.google.com,*.cloud.google.com,*.google-analytics.com,*.google.ca,*.google.cl,*.google.co.in,*.google.co.jp,*.google.co.uk,*.google.com.ar,*.google.com.au,*.google.com.br,*.google.com.co,*.google.com.mx,*.google.com.tr,*.google.com.vn,*.google.de,*.google.es,*.google.fr,*.google.hu,*.google.it,*.google.nl,*.google.pl,*.google.pt,*.googleadapis.com,*.googleapis.cn,*.googlecommerce.com,*.googlevideo.com,*.gstatic.cn,*.gstatic.com,*.gvt1.com,*.gvt2.com,*.urchin.com,*.url.google.com,*.youtube-nocookie.com,*.youtube.com,*.youtubeeducation.com,*.ytimg.com,android.com,g.co,goo.gl,google-analytics.com,google.com,googlecommerce.com,urchin.com,youtu.be,youtube.com,youtubeeducation.com
2

In addition to using awk, you can use sed:

openssl x509 -in cert_file_name.crt -noout -text | awk '/DNS:/' | sed 's/DNS://g'

This will turn a SAN list from:

DNS:domain1.com, DNS: DNS:domain3.com, DNS:sub.domain3.com

to

domain1.com, domain3.com, sub.domain3.com

I think the best way to do this is this:

openssl x509 -in cert_file_name.crt -noout -ext subjectAltName

You can check more about the -ext flag in the official documentation of openssl here:

This way you'll only get the relevant information you need with one command, no need to use other softwares like awk and sed.

1

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like