---
title: "OpenSSL Commands Cheatsheet"
slug: "openssl-commands"
category: "cheatsheets"
tags: ["cheatsheets", "openssl", "ssl", "tls", "certificates", "security", "cli", "reference"]
status: "stable"
last_updated: 2026-05-14
summary: "OpenSSL command reference: generate keys and certs, inspect certificates, test TLS connections, convert formats, and verify chains."
related:
  [
    "[[cheatsheets/ssh-config]]",
    "[[ops/cloudflare-security-headers]]",
    "[[ops/hostinger-vps]]",
    "[[tooling/github-secrets]]",
    "[[cheatsheets/curl-flags]]",
    "[[coding/shell]]",
    "[[cheatsheets/index|Cheatsheets]]",
  ]
---

## Overview

`openssl` is the Swiss-army knife for certificates, keys, and TLS debugging. The command surface is large; this card covers the 20 % of commands that handle 80 % of real tasks: key generation, self-signed certs, reading existing certs, live server testing, and format conversion. For SSH key management patterns, see [[cheatsheets/ssh-config]].

## Generate keys

Prefer Ed25519 for SSH; RSA 4096 or ECDSA P-256 for TLS.

| Command | Key type | Notes |
| --- | --- | --- |
| `openssl genrsa -out key.pem 4096` | RSA 4096 | Widely supported; larger than needed for modern TLS. |
| `openssl ecparam -name prime256v1 -genkey -noout -out ec.key` | ECDSA P-256 | Preferred for TLS; smaller and faster than RSA 2048. |
| `openssl genpkey -algorithm ed25519 -out ed.key` | Ed25519 | Best for SSH; not all TLS stacks support it yet. |
| `openssl rsa -in key.pem -pubout -out pub.pem` | Extract public key | From an existing RSA private key. |
| `openssl ec -in ec.key -pubout -out ec_pub.pem` | Extract public key | From an existing EC private key. |

Never commit a private key to version control. Store secrets via [[tooling/github-secrets]] or a secrets manager.

## Generate certificates

| Command | What it creates |
| --- | --- |
| `openssl req -new -key key.pem -out csr.pem` | Certificate Signing Request (CSR); submit to a CA. |
| `openssl req -x509 -new -nodes -key key.pem -sha256 -days 365 -out cert.pem` | Self-signed cert; not trusted by browsers, but fine for local dev and mutual TLS. |
| `openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes` | Generate key and self-signed cert in one step. |
| `openssl req -new -newkey ec:<(openssl ecparam -name prime256v1) -keyout ec.key -out ec.csr -nodes` | EC key and CSR together. |

```bash
# Self-signed with Subject Alternative Names (required by Chrome/Firefox)
openssl req -x509 -newkey rsa:4096 -sha256 -days 365 -nodes \
  -keyout localhost.key -out localhost.crt \
  -subj "/CN=localhost" \
  -addext "subjectAltName=DNS:localhost,IP:127.0.0.1"
```

## Inspect certificates and keys

Read without modifying.

| Command | What it shows |
| --- | --- |
| `openssl x509 -in cert.pem -text -noout` | Full certificate details: subject, issuer, validity, SANs, extensions. |
| `openssl x509 -in cert.pem -noout -dates` | `notBefore` and `notAfter` expiry dates only. |
| `openssl x509 -in cert.pem -noout -subject -issuer` | Subject and issuer one-liners. |
| `openssl x509 -in cert.pem -noout -fingerprint -sha256` | SHA-256 fingerprint for pinning or comparison. |
| `openssl req -in csr.pem -text -noout` | Inspect a CSR before submitting. |
| `openssl rsa -in key.pem -check` | Validate an RSA private key. |
| `openssl verify -CAfile ca.pem cert.pem` | Verify cert against a CA bundle. |
| `openssl crl2pkcs7 -nocrl -certfile chain.pem | openssl pkcs7 -print_certs -noout` | List all certs in a chain file. |

## Test live TLS connections

| Command | What it tests |
| --- | --- |
| `openssl s_client -connect host:443` | Full TLS handshake; dumps certificate chain and cipher chosen. |
| `openssl s_client -connect host:443 -servername host` | Enable SNI (required for virtual-hosted HTTPS). |
| `openssl s_client -connect host:443 -tls1_3` | Force TLS 1.3 only. |
| `openssl s_client -connect host:443 -cipher ECDHE-RSA-AES256-GCM-SHA384` | Test a specific cipher suite. |
| `openssl s_client -starttls smtp -connect host:587` | STARTTLS for SMTP (also works with `imap`, `pop3`, `ftp`). |
| `echo Q \| openssl s_client -connect host:443 2>/dev/null \| openssl x509 -noout -dates` | Check expiry of a live server's cert without saving it. |

## Convert and combine formats

| Conversion | Command |
| --- | --- |
| PEM to DER | `openssl x509 -in cert.pem -outform DER -out cert.der` |
| DER to PEM | `openssl x509 -in cert.der -inform DER -out cert.pem` |
| PEM to PKCS#12 | `openssl pkcs12 -export -out bundle.p12 -inkey key.pem -in cert.pem -certfile chain.pem` |
| PKCS#12 to PEM | `openssl pkcs12 -in bundle.p12 -out all.pem -nodes` |
| Combine cert and chain | `cat cert.pem chain.pem > fullchain.pem` |
| Extract cert from PKCS#12 | `openssl pkcs12 -in bundle.p12 -nokeys -out cert.pem` |

## Common gotchas

- `openssl x509 -text` output uses `Subject Alternative Name` for the hostnames browsers check. The `Common Name` field is ignored by all modern browsers; put the hostname in the SAN extension.
- Self-signed certs without a SAN cause Chrome and Firefox to reject them even on localhost. Always include `-addext "subjectAltName=DNS:localhost"`.
- `openssl s_client` exits after the handshake unless you send data. Pipe `echo Q |` or `printf "HEAD / HTTP/1.0\r\n\r\n" |` to get the full output.
- Key and certificate pairing: `openssl x509 -noout -modulus -in cert.pem | md5sum` and `openssl rsa -noout -modulus -in key.pem | md5sum` must match. Mismatches cause nginx/Apache to refuse to start.
- `openssl pkcs12 -export` without `-legacy` fails on OpenSSL 3 when importing into older Java or Windows tools. Add `-legacy` for compatibility with old importers.
- Default days for CSR signing is 30 in some openssl builds. Always set `-days` explicitly.

## Related

- [[cheatsheets/ssh-config]]
- [[ops/cloudflare-security-headers]]
- [[ops/hostinger-vps]]
- [[tooling/github-secrets]]
- [[cheatsheets/curl-flags]]
- [[coding/shell]]
- [[cheatsheets/index|Cheatsheets]]
