OpenSSL is a surprisingly complex beast, and most developers only ever interact with it through libraries or automated tools. But knowing a few core commands can save you hours of debugging obscure TLS/SSL issues or understanding certificate chains.

Let’s see OpenSSL in action, generating a self-signed certificate and then verifying its chain.

# 1. Generate a private key
openssl genpkey -algorithm RSA -out private.key -pkeyopt rsa_keygen_bits:2048

# 2. Generate a Certificate Signing Request (CSR)
openssl req -new -key private.key -out server.csr -subj "/C=US/ST=California/L=San Francisco/O=MyOrg/CN=localhost"

# 3. Self-sign the CSR to create a certificate
openssl x509 -req -days 365 -in server.csr -signkey private.key -out server.crt

# 4. Verify the certificate and its chain (in this case, just itself)
openssl verify -CAfile server.crt server.crt

The output of openssl verify will be server.crt: OK. This simple sequence demonstrates key generation, certificate signing request creation, and self-signing. You’re essentially creating a public-private key pair, asking for a certificate to be issued for a specific identity (the CN=localhost), and then acting as your own Certificate Authority (CA) to sign that request.

The core problem OpenSSL solves for developers is managing asymmetric cryptography, primarily for secure communication (TLS/SSL) and digital signatures. It allows you to encrypt data with a public key and decrypt it only with the corresponding private key, or vice-versa for signing. This is the bedrock of secure web browsing, API authentication, and much more.

Here are some commands that unlock its power:

1. Generating RSA Private Keys: You’ll almost always start by generating a private key. This is the secret part you never share.

openssl genpkey -algorithm RSA -out my_private_key.pem -pkeyopt rsa_keygen_bits:4096

This command generates a 4096-bit RSA private key and saves it to my_private_key.pem. The rsa_keygen_bits option controls the strength of the key; 2048 is common, but 4096 is more secure.

2. Inspecting Certificates and Keys: Ever get a .crt or .pem file and have no idea what’s inside? openssl x509 and openssl pkey are your friends.

To view certificate details:

openssl x509 -in my_certificate.crt -text -noout

This will dump a human-readable version of the certificate, including its subject, issuer, validity dates, public key details, and extensions. The -noout flag prevents printing the raw encoded certificate, and -text shows the formatted details.

To inspect a private key (without revealing the key itself):

openssl pkey -in my_private_key.pem -text -noout

This shows the key type and parameters, but not the actual secret numbers.

3. Creating Certificate Signing Requests (CSRs): When you need a certificate from a real CA, you first create a CSR. This bundles your public key and identity information.

openssl req -new -newkey rsa:2048 -nodes -keyout server.key -out server.csr -subj "/C=US/ST=CA/L=SF/O=MyCompany/CN=myapp.example.com"

This command generates a new 2048-bit RSA private key (server.key) and a CSR (server.csr) in one go. -nodes means "no DES encryption," so your private key won’t be password-protected (useful for automated processes, but be careful!). The -subj flag directly provides the subject distinguished name (DN).

4. Verifying Certificate Chains: This is crucial for debugging TLS connections. You want to ensure a server’s certificate is trusted.

openssl s_client -connect www.google.com:443 -showcerts

This command initiates a TLS connection to www.google.com on port 443 and prints the entire certificate chain presented by the server, starting with the server’s certificate and ending with the root CA certificate. You can then use openssl verify to check the chain’s validity against a set of trusted root certificates (usually found in /etc/ssl/certs/ on Linux).

openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt server.crt

This checks if server.crt is signed by any of the certificates in the ca-certificates.crt bundle.

5. Converting Certificate Formats: You’ll often encounter certificates in different formats (PEM, DER, PKCS12). OpenSSL handles conversions effortlessly.

To convert a DER-encoded certificate to PEM:

openssl x509 -inform der -in certificate.cer -outform pem -out certificate.pem

To create a PKCS12 bundle (which includes the private key and certificate, often password protected):

openssl pkcs12 -export -out my_identity.pfx -inkey private.key -in certificate.crt

You’ll be prompted to set an export password for the .pfx file.

6. Generating Diffie-Hellman Parameters: For perfect forward secrecy in TLS, Diffie-Hellman (DH) key exchange is used. Generating strong DH parameters is important.

openssl dhparam -out dhparam.pem 2048

This generates a 2048-bit DH parameter file. Longer bit lengths (e.g., 4096) offer greater security but increase computation time and handshake latency. For modern TLS, 2048 bits is a common baseline.

Most people know about openssl s_client for testing TLS connections, but they often don’t realize it can also output the entire certificate chain presented by the server. This is invaluable for diagnosing why a client might distrust a server’s certificate; you can see exactly which intermediate certificates are missing or are invalid in the chain presented.

The next step in mastering OpenSSL is understanding how to use it for secure message signing and verification.

Want structured learning?

Take the full Cryptography course →