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)…
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).
Introduction

OpenSSL is the “Swiss Army Knife” of security, but its syntax is notoriously difficult to remember. Every admin has a text file somewhere with these exact commands saved.
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.
Understanding the Certificate Lifecycle
Here is visual context, a diagram explaining the SSL / TLS handshake and Certificate Request (CSR)
sequenceDiagram
participant Admin as Sysadmin (OpenSSL)
participant CA as Certificate Authority
participant SVR as Web Server
Note over Admin: 1. Generate Private Key & CSR
Admin->>CA: Send .csr File
Note over CA: 2. Verify Identity & Sign
CA-->>Admin: Return Signed .crt / .pem
Admin->>SVR: 3. Install Key + Certificate
SVR-->>Admin: Secure HTTPS ActiveWorking with remote servers and websites
This section focuses on interacting with live environments to verify the status and security of remote SSL / TLS certificates. By utilizing the s_client command, you can inspect active certificates, check expiration dates, and test for specific cipher suite support. These tools are indispensable for ensuring that your web and mail servers are correctly configured and maintaining secure connections for your users.
Having trouble with Qualys reporting ‘Public Server Param Reuse‘? See my guide on disabling ECDH key reuse in IIS.
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 a Let’s Encrypt certificate installed. Note that s_client keeps the connection open and waits for input, so the command seems to hang. Pipe a string into it so s_client gets input followed by EOF and returns you to the PowerShell prompt immediately: use "" for a website, or "QUIT" for a mail server. The 2>&1 is unrelated to the hanging; it merely merges s_client‘s status output (stderr) into stdout so it can be piped on to openssl x509.
One of the most common tasks for a sysadmin is checking if a remote web server is sending the correct certificate chain. This command is a lifesaver:
openssl s_client -connect www.google.com:443 -showcerts It helps debug “Certificate Not Trusted” errors in real-time.
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:
"QUIT`r`n" | openssl.exe s_client -connect smtp.example.com:25 -starttls smtp 2>&1 | openssl.exe x509 -enddate -noout For websites
# gets notBefore and notAfter date
"" | openssl.exe s_client -connect www.example.org:443 2>&1 | openssl x509 -noout -dates # gets only notAfter date
"" | openssl.exe s_client -connect www.example.org:443 2>&1 | openssl x509 -enddate -noout Test connections using specific TLS cipher suites
If you need to test whether the remote endpoint accepts an specific TLS ciphersuite you can use s_client parameter -cipher and the specific OpenSSL ciphersuite:
"" | 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.
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:
"QUIT`r`n" | openssl s_client -connect smtp.example.com:25 -starttls smtp See Test SMTP authentication and StartTLS for more information and use cases.
Found this guide helpful? You can support my independent deep dives into Windows Server and DevOps by donating via PayPal. Every bit of support helps keep saotn.org fast and updated!
Inspecting local certificate files (.PEM, .CER, .CRT)
Before deploying certificates to a production environment, it is crucial to verify their local file contents and metadata. In the following sections, we define common formats like PEM and demonstrate how to extract vital information such as Serial Numbers and Subject Alternative Names (SAN). This ensures that your local files are correctly formatted and contain the specific X.509 extensions required for your infrastructure.
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)
- PEM files are base64 with
View details of .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 digital 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 Extracting specific fields from .PEM files
Print SerialNumber and specific named fields
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. Other specific named fields are subject, issuer, dates, fingerprint and pubkey. Use them as shown here:
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.
For a nice comma separated list of subject alternative names, use:
$SANs = openssl x509 -in file.pfx -noout -ext subjectAltName You can create a handy string with DNS names – comma separated – from this using string manipulation in PowerShell. To do this, use Select-Object, Split, Replace, and Join-String. Apply that to your variable $SANs:
# ($SANs | Select-Object -Unique -Last 1) -split(":") -replace " DNS" | Select-Object -Skip 1 | Join-String
([regex]::Matches($SANs,'DNS:([^,\s]+)') | ForEach-Object { $_.Groups[1].Value }) -join ',' Your comma separated list of subject alternative names for example (I added spaces):
example.nl, website-test.example.nl, websitecms-test.example.nl, intranet.example.nl, intranetcms.example.nl, portal-test.example.nl, portal.example.nl, portalbase-test.example.nl, portalbase.example.nl, website-test.example.nl, www.example.nl When working with legacy encryption algorithms like RC2-40-CBC (see the unsupported algorithm error below), you need to use openssl pkc12 with the -legacy parameter and pipe its output through openssl x509:
$SANS = openssl pkcs12 -in cert.pfx -legacy -nokeys -clcerts | openssl x509 -noout -ext subjectAltName
([regex]::Matches($SANs,'DNS:([^,\s]+)') | ForEach-Object { $_.Groups[1].Value }) -join ',' Overview: 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)
Managing CSRs and PFX (PKCS#12) Files
Efficiently managing certificate requests and bundled files is a key skill for any systems administrator handling encryption. This part of the guide explains how to inspect Certificate Signing Requests (CSRs) and how to package private keys and certificates into PFX files. Understanding these workflows allows for secure certificate portability and ensures that all intended hostnames are properly included before signing.
Inspect Subject Alternative Names (SAN) in a CSR
If someone provided you with an certificate signing request – or CSR – you verify the hostnames with the following openssl.exe command:
# Use PowerShell Select-String filtering out openssl.exe output
# to select only lines having DNS
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.
Create a PFX certificate from .PEM and private key 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:
- 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 - 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 PFX file details and Subject information
The subject, issuer and friendlyName of an .PFX certificate file is reviewed using:
# Get PFX details like Subject, Issuer and FriendlyName
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).
Export a PFX file from Windows to use in Linux / apache
Exporting a PFX from Windows to use in Linux/Apache is a common pain point.
When converting a .pfx to .pem, OpenSSL will often bundle the private key and the certificate into one file. If your application requires them separately, use the -nocerts flag to extract only the key, and the -nokeys flag to extract only the certificate.
Troubleshooting & common errors
Technical errors are inevitable when working with varying versions of security libraries and legacy encryption standards. This section provides solutions for common issues, such as the “unsupported algorithm” error encountered when handling older PKCS#12 files. By using the techniques described here, you can overcome compatibility hurdles and maintain a robust, functional certificate management pipeline.
If you encounter an “Unsupported Algorithm” error while working with older .pfx files, don’t panic – your file isn’t corrupted. OpenSSL 3.0+ simply disables older encryption methods by default. Adding the -legacy -provider default flags allows you to bypass this security restriction for compatibility with legacy Windows or Java exports.
Fix: Unsupported algorithm error when extracting from PKCS#12
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.
This happens because OpenSSL 3.0 moved several older, less secure cryptographic algorithms (like RC2-40-CBC or 3DES) into a separate Legacy Provider. By default, this provider is not loaded, causing OpenSSL to fail when it encounters a file encrypted with these older standards.
The algorithm is still available in OpenSSL’s legacy provider. Try adding “-legacy” to your command-prompt. To successfully process these files, you must tell OpenSSL to load the legacy algorithms. This requires two specific flags:
-provider default: Ensures the modern algorithms are still available alongside the old ones.-legacy: Enables the legacy provider.
openssl.exe pkcs12 -info -in certfile.pfx -legacy This makes the updated command:
openssl pkcs12 -in backup-cert.pfx -nocerts -out key.pem -legacy -provider default Best Practices: modernizing your SSL / TLS commands
While RSA 2048-bit is the historical standard, modern security requirements are shifting toward Elliptic Curve Cryptography (ECC). ECC offers stronger security with much smaller key sizes, which results in faster SSL handshakes and lower CPU overhead.
To generate a modern ECDSA private key and CSR in one go, use:
openssl.exe ecparam -name prime256v1 -genkey -noout -out ecc-private.key
openssl.exe req -new -key ecc-private.key -out ecc-request.csr Advanced: moving beyond File-Based Keys
Did you know? While OpenSSL is great for managing file-based certificates, keeping private keys on a standard filesystem can be a security risk. For high-stakes environments, you can use OpenSSL to interface with hardware security modules. If you’re interested in hardware-backed security, check out my guide on securing OpenSSH with YubiKey.
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“.
We’ve covered everything from basic file inspections to modernizing your workflow with ECC and hardware-backed keys.
Summary
- This article covers OpenSSL basic TLS tasks for working with SSL / TLS certificates.
- Key commands include `s_client` for inspecting remote certificates and checking expiration dates.
- You can manage local certificate files, extract specific fields, and create PFX certificates from PEM files.
- Additionally, troubleshooting common errors and understanding certificate extensions are essential skills.
- The author references useful links and highlights that some content originated from ChatGPT.
One-time donation
Your donation 💸 helps support me in the ongoing costs running a blog like this one. Costs like coffee ☕, web hosting services 🖥 , article research 🔎 , and so on. Thank you 🙏 for your support❤️ https://www.paypal.com/paypalme/jreilink.
Parts of this post were generated by ChatGPT and Google Gemini, based on quesions I asked it and command-line options I required.