OpenSSL Cheatsheet

Keys

Use this OpenSSL reference while you build software engineering projects, review code, or refresh the syntax you reach for most.

Generate a private key

genpkey is the modern front end and handles every algorithm. genrsa and ecparam still work but are legacy shortcuts.

# RSA 2048 (the safe default for TLS and CSRs)
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out key.pem

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

# EC P-256, what most CAs and browsers prefer today
openssl genpkey -algorithm EC \
  -pkeyopt ec_paramgen_curve:prime256v1 -out ec.key

# EC P-384
openssl genpkey -algorithm EC \
  -pkeyopt ec_paramgen_curve:secp384r1 -out ec384.key

# Ed25519, one line, no parameters to pick
openssl genpkey -algorithm ED25519 -out ed.key

# X25519 for key agreement (not signatures)
openssl genpkey -algorithm X25519 -out x25519.key

The legacy equivalents, still seen in every older runbook:

openssl genrsa -out key.pem 2048
openssl ecparam -name prime256v1 -genkey -noout -out ec.key

Encrypted keys

Add a cipher flag to wrap the key in a passphrase. OpenSSL 3.x writes PKCS#8 ENCRYPTED PRIVATE KEY here, not the old Proc-Type: 4,ENCRYPTED PEM headers.

# Generate encrypted, prompting for the passphrase
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 \
  -aes-256-cbc -out key.enc.pem

# Encrypt an existing plaintext key
openssl pkey -in key.pem -aes-256-cbc -out key.enc.pem

# Strip the passphrase (needed by many web servers at boot)
openssl pkey -in key.enc.pem -out key.pem

# Non-interactive passphrase sources
openssl pkey -in key.pem -aes-256-cbc -passout pass:secret -out k.pem
openssl pkey -in key.pem -aes-256-cbc -passout file:pw.txt -out k.pem
openssl pkey -in key.pem -aes-256-cbc -passout env:KEYPW -out k.pem

-passout pass:secret puts the passphrase in your shell history and in /proc. Use file: or env: on anything real.

Public keys

The public key is derived from the private key, never generated separately.

openssl pkey -in key.pem -pubout -out pub.pem
openssl genpkey -algorithm RSA -out key.pem -outpubkey pub.pem
openssl rsa -in key.pem -pubout -out pub.pem        # legacy, RSA only

An SSH-format public key comes from ssh-keygen, not OpenSSL:

ssh-keygen -y -f key.pem > key.pub

Inspect and verify a key

openssl pkey -in key.pem -noout -text        # full dump
openssl pkey -in key.pem -noout -text_pub    # public parts only
openssl pkey -in key.pem -noout              # silent = parsed fine
openssl rsa  -in key.pem -check -noout       # RSA consistency check
openssl ec   -in ec.key  -check -noout       # EC consistency check

Read the size and type without wading through the hex dump:

$ openssl pkey -in key.pem -noout -text | head -1
Private-Key: (2048 bit, 2 primes)

$ openssl pkey -in ec.key -noout -text | grep -E 'ASN1|Private-Key'
Private-Key: (256 bit)
ASN1 OID: prime256v1

Key options that matter

OptionMeaning
-algorithm RSA|EC|ED25519|X25519Key type
-pkeyopt rsa_keygen_bits:NRSA modulus size
-pkeyopt rsa_keygen_pubexp:NPublic exponent, default 65537
-pkeyopt ec_paramgen_curve:NAMENamed curve
-pkeyopt ec_param_enc:named_curveStore curve by name, not explicit params
-outform PEM|DEROutput encoding
-outpubkey FILEWrite the matching public key too
-aes-256-cbc, -aes-128-cbc, -des3Encrypt the output key
-pass, -passoutPassphrase source
-text, -nooutPrint details, suppress the encoded key

Curve names come from openssl ecparam -list_curves. In practice only prime256v1 (NIST P-256), secp384r1 (P-384), and secp521r1 (P-521) are widely accepted by public CAs, plus Ed25519 at a few of them.

Gotchas

- prime256v1 and secp256r1 and NIST P-256 are the same curve. OpenSSL prints prime256v1. secp256k1 is the Bitcoin curve and is not accepted for TLS. - genrsa -out key.pem 2048 puts the size last, after the output file. Reversing them silently writes a file named 2048. - OpenSSL 3.x refuses RSA keys under 512 bits and warns loudly under 2048 in many distro builds. - -nodes is spelled -noenc since 3.0. -nodes still works, it just prints nothing about being deprecated in most builds. - openssl rsa on an EC key fails. openssl pkey handles every type, so prefer it in scripts you do not control the inputs of. - A key file with BEGIN OPENSSH PRIVATE KEY is not PEM PKCS#8. Convert with ssh-keygen -p -m PKCS8 -f key.