Use OpenSSL for basic SSL/TLS tasks

Home » Useful » Use OpenSSL for basic SSL/TLS tasks

In this post I outline some basic OpenSSL commands you can use in your day to day job when it involves working with SSL/TLS certificates. For example you use OpenSSL to get a certificate’s SerialNumber or to verify the SAN (Subject Alternative Names).

OpenSSL has a lot of sub commands:

When working with TLS certificates you mostly use the s_client standard command. This command allows you to inspect certificates, work in a SMTP stream to send email, and so on. In Windows you install OpenSSL using winget or by using its installer file. See install OpenSSL in Windows for all the details.

I have openssl.exe in my path environment ($env:path) so I don’t have to type the full path to my openssl.exe binary. Further I have ShiningLight.OpenSSL.Light OpenSSL installed, you may have FireDaemon OpenSSL available. No worries.

Retrieve and inspect a website’s current SSL/TLS certificate

Execute the following command to inspect a remote website’s current TLS certificate:

openssl.exe s_client -tls1_2 -servername HOSTNAME -connect IP_ADDRESS:443

Substitute HOSTNAME and IP_ADDRESS with their respected values. For Saotn.org:

openssl.exe s_client -tls1_2 -servername www.saotn.org -connect [2a00:f60::1:51]:443

this results in (partly):

Connecting to 2a00:f60::1:51
CONNECTED(0000017C)
depth=1 C=US, O=Let's Encrypt, CN=R11
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN=*.saotn.org
verify return:1
---
Certificate chain
 0 s:CN=*.saotn.org
   i:C=US, O=Let's Encrypt, CN=R11
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
   v:NotBefore: Jun 28 05:01:16 2025 GMT; NotAfter: Sep 26 05:01:15 2025 GMT
 1 s:C=US, O=Let's Encrypt, CN=R11
   i:C=US, O=Internet Security Research Group, CN=ISRG Root X1
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
   v:NotBefore: Mar 13 00:00:00 2024 GMT; NotAfter: Mar 12 23:59:59 2027 GMT
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIE/TCCA+WgAwIBAgISBhUb4d83bGGOx3aYxZgmUCT+MA0GCSqGSIb3DQEBCwUA
MDMxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQwwCgYDVQQD
EwNSMTEwHhcNMjUwNjI4MDUwMTE2WhcNMjUwOTI2MDUwMTE1WjAWMRQwEgYDVQQD
DAsqLnNhb3RuLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANeF
AO2V8tkgeVzAr71Xmczc8szmaOaBgNge979uS8VhR6aMlJ9uJ6lGT26Jflj2j/Ap
om4SWYQUxrgy30IZ54Y1BxFbbGFMP23NB4h0f1bqN2rKku+G7Py526VtXGWO5XNm
Sfc2yia0JzfemtkVfDWDb76dxFGfYp90S1VmB+oHvzQUyFMCUjBheLdJC0+lJOOo
Mwq8pCx3g8QPP1MvNmCNs+F+f63O4y9Q8HTmW5pefeB5g6/DmOSPhXR2oUXrj99c
YussB+UA7g+03JGoyuovfqKiOqgk9q0LjAYjb3FGdJgLzj57HbgXlo3cJSsU+m+T
7cTS978lzjhc00S/MfsCAwEAAaOCAiYwggIiMA4GA1UdDwEB/wQEAwIFoDAdBgNV
HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4E
FgQUBVzoGVoVudrFupJl19XmHaAMSkUwHwYDVR0jBBgwFoAUxc9GpOr0w8B6bJXE
LbBeki8m47kwMwYIKwYBBQUHAQEEJzAlMCMGCCsGAQUFBzAChhdodHRwOi8vcjEx
LmkubGVuY3Iub3JnLzAhBgNVHREEGjAYggsqLnNhb3RuLm9yZ4IJc2FvdG4ub3Jn
MBMGA1UdIAQMMAowCAYGZ4EMAQIBMC8GA1UdHwQoMCYwJKAioCCGHmh0dHA6Ly9y
MTEuYy5sZW5jci5vcmcvMTI3LmNybDCCAQMGCisGAQQB1nkCBAIEgfQEgfEA7wB1
AA3h8jAr0w3BQGISCepVLvxHdHyx1+kw7w5CHrR+Tqo0AAABl7Ue1jUAAAQDAEYw
RAIgOGcZXy5op6SLcwECwXoFSVb5vsc8r8MS/aMO2LacvxkCIFBj7MO8eguMQgY7
LZHZqzjX0qWSUFLSyOfUsGMTG54gAHYAzPsPaoVxCWX+lZtTzumyfCLphVwNl422
qX5UwP5MDbAAAAGXtR7XDwAABAMARzBFAiBz2MfJJ4KGhPLB5+XAETuMg4+2aPjc
wyGP7Vs2Gfe19QIhAIpDRHBmu2pT5W+t2m8Fd5R7JxKakEpC/aqBUA1EsHoMMA0G
CSqGSIb3DQEBCwUAA4IBAQApxtjM5WhBuWb3p4n8/IYM6JR8JI/ySi0q+NMVWN7X
Qx+nRJG4EQGDEeqcp02ztQeTvnvdVkSktQ0rI/koy8A8BSKXOZ4MyChZZ9jucD4d
wiQZjAM18RSIJOS4IrJ/J4Ct1k8sZlG0jeXghd5AsdtQyqMveq8TXDCfZqNAKRmi
YKBCb+oPzG8054gd7JLBL4wDT3J05ksQ33w2C8BiFbIDqaKbS12roTP9bdGrrgpx
kSSDLwba23v4IEtpfDmF3U6Og98N2VGeoowCXNdxbA9b0OfGzJNfMMlYPC5VYZ0S
laVi2cZPNCoQcux0TB5Q345N9AjyRgmjMBh9h4H7GEY+
-----END CERTIFICATE-----
subject=CN=*.saotn.org
issuer=C=US, O=Let's Encrypt, CN=R11
---

Which tells you my site has an Let’s Encrypt certificate installed. Please note this command hangs or waits. Use Write-Host -NoNewLine "QUIT\r" and pipe to 2>&1 as shown below to return to your PowerShell prompt immediately.

Check TLS/SSL certificate expiration date

This one-liner checks the TLS/SSL certificate expiration date, from the Linux command-prompt (Bash) using openssl:

echo | openssl s_client -connect mx.example.com:25 -starttls smtp | openssl x509 -noout -dates
echo | openssl s_client -connect ftp.example.com:21 -starttls ftp | openssl x509 -noout -dates

In Windows you can run the following command to obtain the SSL Certificate Expiration Date. For SMTP servers:

Write-Host -NoNewLine "QUIT\r" | c:\path\to\bin\openssl.exe s_client -connect smtp.example.com:25 -starttls smtp | c:\path\to\bin\openssl.exe x509 -enddate -noout

For websites

# gets notBefore and notAfter date
write-host -NoNewline "" | openssl.exe s_client -connect www.example.org:443 2>&1 | openssl x509 -noout -dates
# gets only notAfter date
write-host -NoNewline "" | openssl.exe s_client -connect www.example.org:443 2>&1 | openssl x509 -enddate -noout

Connect using an specific TLS ciphersuite

If you need to test whether the remote endpoint accepts an specific TLS ciphersuite you can use s_client‘s parameter -cipher and the specific OpenSSL ciphersuite:

Write-Host -NoNewline "" | openssl.exe s_client -cipher "ECDHE-RSA-AES256-GCM-SHA384" -connect example.org:443
Connecting to 104.18.3.24
CONNECTED(000000C8)
depth=3 C=US, O=SSL Corporation, CN=SSL.com TLS ECC Root CA 2022
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=2 C=US, O=SSL Corporation, CN=SSL.com TLS Transit ECC CA R2
verify return:1
depth=1 C=US, O=SSL Corporation, CN=Cloudflare TLS Issuing ECC CA 3
verify return:1
depth=0 CN=example.org
verify return:1
---
Certificate chain
 0 s:CN=example.org
   i:C=US, O=SSL Corporation, CN=Cloudflare TLS Issuing ECC CA 3
   a:PKEY: EC, (prime256v1); sigalg: ecdsa-with-SHA256
   v:NotBefore: Dec 10 20:01:57 2025 GMT; NotAfter: Mar 10 20:06:47 2026 GMT
 1 s:C=US, O=SSL Corporation, CN=Cloudflare TLS Issuing ECC CA 3
   i:C=US, O=SSL Corporation, CN=SSL.com TLS Transit ECC CA R2
   a:PKEY: EC, (prime256v1); sigalg: ecdsa-with-SHA384
   v:NotBefore: May 29 19:49:45 2025 GMT; NotAfter: May 27 19:49:44 2035 GMT
 2 s:C=US, O=SSL Corporation, CN=SSL.com TLS Transit ECC CA R2
   i:C=US, O=SSL Corporation, CN=SSL.com TLS ECC Root CA 2022
   a:PKEY: EC, (secp384r1); sigalg: ecdsa-with-SHA384
   v:NotBefore: Oct 21 17:02:23 2022 GMT; NotAfter: Oct 17 17:02:22 2037 GMT
 3 s:C=US, O=SSL Corporation, CN=SSL.com TLS ECC Root CA 2022
   i:C=GB, ST=Greater Manchester, L=Salford, O=Comodo CA Limited, CN=AAA Certificate Services
   a:PKEY: EC, (secp384r1); sigalg: sha256WithRSAEncryption
   v:NotBefore: Aug  1 00:00:00 2025 GMT; NotAfter: Dec 31 23:59:59 2028 GMT
---
Server certificate
-----BEGIN CERTIFICATE-----
MIID6DCCA46gAwIBAgIQEYBoTkGpcLroTC5ttYH9zzAKBggqhkjOPQQDAjBRMQsw
CQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSgwJgYDVQQDDB9D
bG91ZGZsYXJlIFRMUyBJc3N1aW5nIEVDQyBDQSAzMB4XDTI1MTIxMDIwMDE1N1oX
DTI2MDMxMDIwMDY0N1owFjEUMBIGA1UEAwwLZXhhbXBsZS5vcmcwWTATBgcqhkjO
PQIBBggqhkjOPQMBBwNCAAQ7nVOipqFwMiHmwWzrClgKckUB+Tr80Vqc8Q53He8+
tHG/+atkZNtxla/4gIqHDfBEaOT8H/QQ5LWwP4XamKuIo4ICgTCCAn0wDAYDVR0T
AQH/BAIwADAfBgNVHSMEGDAWgBSDA/3n9vVKTRVB9O0iFtMyCj7KZjBsBggrBgEF
BQcBAQRgMF4wOQYIKwYBBQUHMAKGLWh0dHA6Ly9pLmNmLWkuc3NsLmNvbS9DbG91
ZGZsYXJlLVRMUy1JLUUzLmNlcjAhBggrBgEFBQcwAYYVaHR0cDovL28uY2YtaS5z
c2wuY29tMCUGA1UdEQQeMByCC2V4YW1wbGUub3Jngg0qLmV4YW1wbGUub3JnMCMG
A1UdIAQcMBowCAYGZ4EMAQIBMA4GDCsGAQQBgqkwAQMBATATBgNVHSUEDDAKBggr
BgEFBQcDATBTBgNVHR8ETDBKMEigRqBEhkJodHRwOi8vYy5jZi1pLnNzbC5jb20v
YWU4MDFlZDFjNTViYjU3OWQ3OTIwOGIwZDc3MmFjZmI4Y2MzYTIwOC5jcmwwDgYD
VR0PAQH/BAQDAgeAMA8GCSsGAQQBgtpLLAQCBQAwggEFBgorBgEEAdZ5AgQCBIH2
BIHzAPEAdwBkEcRspBLsp4kcogIuALyrTygH1B41J6vq/tUDyX3N8AAAAZsJ5FmH
AAAEAwBIMEYCIQD+GWlen2LCA2xGmHFGpXvEkLsYv5NRRhcDr7cOJfInRgIhANtc
ZkpYhVxmQnDvzT8yhTWox8gXzvwk9XoA5RnXIldPAHYAyzj3FYl8hKFEX1vB3fvJ
bvKaWc1HCmkFhbDLFMMUWOcAAAGbCeRZtAAABAMARzBFAiEAuEbrL1EWhNoVEAj9
IRUVpqeTeKrP2hcmej8QGqAaGiICIHazppnXqUJp+YmKNs2Q81h+uUd413uGspyZ
elRXfEw1MAoGCCqGSM49BAMCA0gAMEUCIGD0LUiec6tEtyNR37qlbwOU+dHKr0rt
eTRwgKFdQ9sQAiEA5i+cOS8jLn/zGjugOgf9Ew+NKrnSlI7f8IaEULYfcCY=
-----END CERTIFICATE-----
subject=CN=example.org
issuer=C=US, O=SSL Corporation, CN=Cloudflare TLS Issuing ECC CA 3
---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: ecdsa_secp256r1_sha256
Negotiated TLS1.3 group: X25519MLKEM768
---
SSL handshake has read 5073 bytes and written 1570 bytes
Verification error: unable to get local issuer certificate
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Protocol: TLSv1.3
Server public key is 256 bit
This TLS version forbids renegotiation.
No ALPN negotiated
Early data was not sent
Verify return code: 20 (unable to get local issuer certificate)
---
DONE

Pipe this command through openssl.exe x509 -noout -text to view remote certificate information like Signature Algorithm, Issuer, Validity, Subject and Subject Alternative Name.

See below for more info.

Verify StartTLS for SMTP-, POP3- or IMAP servers

To check whether your (SMTP-, POP3-, or IMAP) mail server supports StartTLS, use the following OpenSSL command:

openssl s_client -connect imap.example.com:143 -starttls imap
openssl s_client -connect pop.example.com:110 -starttls pop3
openssl s_client -connect smtp.example.com:25 -starttls smtp

In Windows you must add “Write-Host -NoNewline “QUIT\r”” again:

Write-Host -NoNewline "QUIT\r" | openssl s_client -connect smtp.example.com:25 -starttls smtp

SerialNumber from .PEM file

How to get serialNumber from a certificate in PEM format?

Another task for OpenSSL could be: Suppose you have a .PEM file and you need to get the SerialNumber from it, use the following openssl.exe command:

(& openssl.exe x509 -noout -serial -in .\dev.saotn.org.pem).split("=")[1]

The output is the SerialNumber.

What exactly is a .PEM file?

Taken from “sysadmin1138” great explanation on Server fault:

  • .pem – Defined in RFC 1422 (part of a series from 1421 through 1424) this is a container format that may include just the public certificate (such as with Apache installs, and CA certificate files /etc/ssl/certs), or may include an entire certificate chain including public key, private key, and root certificates. Confusingly, it may also encode a CSR (e.g. as used here) as the PKCS10 format can be translated into PEM. The name is from Privacy Enhanced Mail (PEM), a failed method for secure email but the container format it used lives on, and is a base64 translation of the x509 ASN.1 keys.
  • In short:
    • PEM files are base64 with —–BEGIN CERTIFICATE—–
    • DER files are binary (often .cer on Windows)

Print only specific named fields

openssl x509 -in cert.pem -noout -subject
openssl x509 -in cert.pem -noout -issuer
openssl x509 -in cert.pem -noout -serial
openssl x509 -in cert.pem -noout -dates
openssl x509 -in cert.pem -noout -fingerprint -sha256
openssl x509 -in cert.pem -noout -pubkey

Print only Subject Alternative Names (SANs) using X.509 extensions

openssl x509 -in cert.pem -noout -ext subjectAltName

Did you know you can specify multiple -ext flags? Use openssl x509 -in cert.pem -noout -ext subjectAltName -ext keyUsage -ext extendedKeyUsage for example.

Most common certificate extensions

These names generally work with -ext \<name\> when present in the certificate.

Identity / naming

  • subjectAltName (SAN): DNS names, IPs, URIs, emails (most important for TLS hostname matching)
  • issuerAltName: less common, but appears in some setups
  • subjectKeyIdentifier: identifier for the subject public key
  • authorityKeyIdentifier: identifier linking to issuer key (helps chain building)

Trust / constraints

  • basicConstraints: CA:TRUE/FALSE, path length (critical for CA certs)
  • nameConstraints: common in constrained intermediate CAs (enterprise / PKI)
  • policyConstraints, inhibitAnyPolicy, certificatePolicies: more PKI-heavy

Usage

  • keyUsage: digitalSignature, keyEncipherment, keyCertSign, cRLSign, etc.
  • extendedKeyUsage: serverAuth, clientAuth, codeSigning, emailProtection, etc.

Revocation / AIA pointers

  • crlDistributionPoints: where to fetch CRLs
  • authorityInfoAccess: often contains OCSP URL and “CA Issuers” URL

Other commonly used OpenSSL extensions

  • signatureAlgorithm (not an extension; shown in -text output)
  • subjectPublicKeyInfo (not an extension; but public key info is shown; -pubkey prints it)

Create PFX certificate from certificate .pem and private key .pem files

If you have obtained a certificate .PEM file and its private key file in .PEM format, you export it to a PFX certificate file with openssl.exe. Here is how:

  1. First check whether the files belong to eachother, verify their hashes. They must match:
openssl.exe x509 -noout -modulus -in certificate.pem | openssl md5

# fill out the certificate file's password, if requested
openssl.exe rsa -noout -modulus -in privatekey.pem | openssl md5
  1. Next, export to PFX. Again, fill out the certificate file’s password and a new PFX password
openssl.exe pkcs12 -export -out certificate .pfx -inkey privatekey.pem -in certificate.pem -name "My Certificate FriendlyName"
Enter pass phrase for privatekey.pem:
Enter Export Password:
Verifying - Enter Export Password:

Done 🙂

View details of a digital (X.509) certificate .cer and .crt files

CER files are mostly base64-encoded binary files, and CRT files are base64-encoded ASCII files. View the contents and details of X.509 .cer and .crt certificate files using openssl.exe:

openssl.exe x509 -noout -text -in .\CRTfile.crt
openssl.exe x509 -noout -text -in .\CERfile.cer

SAN (Subject Alternative Names) from Certificate Signing Request (CSR)

If someone provided you with an certificate signing request – or CSR – you verify the hostnames with the following openssl.exe command:

openssl.exe req -in '.\CSRfile.csr' -text -noout | Select-String DNS

This prints out hte DNS names, also known as Subject ALternative Names or SANs.

PFX file’s Subject

The subject, issuer and friendlyName of an .PFX certificate file is reviewed using:

openssl.exe pkcs12 -info -in certfile.pfx

Do note this requests the certificate’s Import Password and PEM pass phrase (even a couple of times). In the certificate information you find

Bag Attributes
    localKeyID: 01 00 00 00
    friendlyName: *.saotn.org - 2026
subject=CN=*.saotn.org
C=US, O=Let's Encrypt, CN=R11

Pipe the openssl.exe pkcs12 command through openssl.exe x509 for even more information:

openssl.exe pkcs12 -info -in certfile.pfx | openssl.exe x509 -noout -text

Unfortunately this only works with PowerShell 5.1, PWSH 7.4 returns an error and you have to add a function to parse the openssl pkcs12 output, see https://github.com/PowerShell/PowerShell/issues/20827#issuecomment-1836203178. You can also pipe to 2>&1:

openssl.exe pkcs12 -info -in certfile.pfx 2>&1 | openssl.exe x509 -noout -text

What 2>&1 does is: it redirects standard error (the 2) to the same place as standard output (the 1).

Unsupported algorithm error when extracting public certificate from PKCS#12 file

If the openssl.exe pkcs12 command returns an error message like the following:

MAC: sha1, Iteration 2048
MAC length: 20, salt length: 8
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 2048
Error outputting keys and certificates
38BA0000:error:0308010C:digital envelope routines:inner_evp_generic_fetch:unsupported:..\crypto\evp\evp_fetch.c:375:Global default library context, Algorithm (RC2-40-CBC : 0), Properties ()

Then the file has been encrypted with an unsupported encryption algorithm (RC2-40-CBC). That algorithm is considered legacy and insecure. The algorithm is still available in OpenSSL’s legacy provider. Try adding “-legacy” to your command line:

openssl.exe pkcs12 -info -in certfile.pfx -legacy

Conclusion

This post provided you with some basic OpenSSL tasks for working with certificates. If you want to work with StartTLS and SMTP, IMAP or POP3 servers, you may find the post Test SMTP authentication and StartTLS interesting. Xolphin has a more extended post “Frequently used OpenSSL Commands“.

Summary

  • This article introduces OpenSSL basic TLS tasks for managing SSL/TLS certificates.
  • Use commands like s_client to inspect certificates and check their validity.
  • You can retrieve SSL/TLS certificate details and expiration dates using specific OpenSSL commands.
  • This guide covers how to handle .PEM files and the significance of Subject Alternative Names (SAN).
  • For further tasks like handling StartTLS and SMTP, refer to additional resources linked within the article.

One-time donation

Please take a second to support Sysadmins of the North and donate, your generosity helps!

Parts of this post were generated by ChatGPT, based on quesions I asked it and command-line options I required.

Jan Reilink
Jan Reilink

In my day to day work, I’m a systems administrator – DevOps / SRE and applications manager at Embrace – The Human Cloud. At Embrace we develop, maintain and host social intranets for our clients. Provide digital services and make working more efficient within various sectors.

Want to support me and donate? Use this link: https://www.paypal.com/paypalme/jreilink.

Articles: 166

Leave a Reply

Your email address will not be published. Required fields are marked *