Generate and verify OpenSSL private keys with genpkey
You will create a private key with OpenSSL's genpkey, save it in a controlled location, and check that it is usable. The examples cover a 2048-bit RSA key, a P-256 EC key, and an encrypted PEM key. Allow about ten minutes, plus the time needed to decide how your application will store and protect the key.
The route
Jump straight to the step you need, or tick off Done means at the end.
You need the OpenSSL command-line tools and a shell. The installed command used for these examples is OpenSSL 3.6.1, while the local openssl-genpkey(1ssl) page identifies its interface as OpenSSL 3.0.13. The core commands below are documented by both. Version-specific options should be checked with openssl genpkey -help on the machine where a script will run.
1. Check the installed command
Start by checking which executable your shell will use and recording its version:
$ command -v openssl
/usr/bin/openssl
$ openssl version
OpenSSL 3.6.1 27 Jan 2026
Your path and version can differ. This matters because genpkey delegates algorithm options to the installed provider implementation. Do not copy a -pkeyopt from a different OpenSSL release without testing it here.
Checkpoint
openssl version should complete successfully, and openssl genpkey -help should list -algorithm, -out, -outform, -pass and -pkeyopt.
2. Generate a 2048-bit RSA key
Choose a new destination and create the key. The command writes PEM by default. The -quiet option suppresses progress dots, which is useful in scripts and makes errors easier to spot:
$ umask 077
$ openssl genpkey -algorithm RSA \
> -pkeyopt rsa_keygen_bits:2048 \
> -out rsa-private.pem -quiet
umask 077 makes newly created files readable and writable only by you. It affects files created by this shell, so use it in a dedicated shell or restore your normal umask afterwards if your workflow depends on one. The RSA key size is explicit here; the manual says RSA defaults to 2048 bits when rsa_keygen_bits is omitted. Its default public exponent is 65537.
Confirm that the file is present without printing the private material:
$ ls -l rsa-private.pem
-rw------- 1 you you 1708 Sep 25 12:00 rsa-private.pem
$ head -1 rsa-private.pem
-----BEGIN PRIVATE KEY-----
The byte count and timestamp will differ. Do not paste the complete PEM file into a ticket, chat or shell transcript. A private key is a credential, not a harmless configuration sample.
3. Verify the key without exposing it
Use openssl pkey to check the key structure and mathematics. It reads the file but sends no key material to standard output:
$ openssl pkey -in rsa-private.pem -check -noout
Key is valid
A non-zero exit status or an error means the file is not a key that this OpenSSL build can validate. Preserve the original file while investigating. If generation failed and left an incomplete destination, remove only that known incomplete file after checking its path. Never use a broad wildcard such as rm *.pem in a directory containing credentials.
For an additional public-key check, derive a public key into a separate file:
$ openssl pkey -in rsa-private.pem -pubout -out rsa-public.pem
$ head -1 rsa-public.pem
-----BEGIN PUBLIC KEY-----
The public file can normally be distributed, but keep it associated with the correct private key. The public output does not let you reconstruct the private key.
4. Generate an EC key with an explicit curve
For an elliptic-curve key, name the algorithm and curve separately. P-256 is a named curve supported by the local manual and command:
$ openssl genpkey -algorithm EC \
> -pkeyopt ec_paramgen_curve:P-256 \
> -out ec-private.pem -quiet
$ openssl pkey -in ec-private.pem -check -noout
Key is valid
Use the curve required by the software that will consume the key. The spelling accepted by the local build is an implementation detail, so test the exact value rather than assuming that every alias works everywhere. A P-256 key is not interchangeable with an RSA key: applications must support the chosen algorithm and use it for the right operation.
5. Encrypt a private key at rest
Plain PEM output is not encrypted. Add a cipher and a passphrase source when the file may be readable by another account or copied into a backup:
$ umask 077
$ printf '%s\n' 'replace-with-a-long-secret' > key-passphrase.txt
$ chmod 600 key-passphrase.txt
$ openssl genpkey -algorithm RSA \
> -pkeyopt rsa_keygen_bits:2048 \
> -aes-256-cbc -pass file:key-passphrase.txt \
> -out rsa-encrypted.pem -quiet
$ openssl pkey -in rsa-encrypted.pem \
> -passin file:key-passphrase.txt -check -noout
Key is valid
The manual accepts cipher names as options and uses -pass to select the output passphrase source. A passphrase file is convenient for a reproducible test, but it is itself a secret and must be protected. For a production service, use the secret-management mechanism expected by that service rather than committing this file to a repository. Avoid putting a real passphrase directly in the command line, where it can be captured by shell history or process inspection.
Security boundary
Encryption protects the key file if the passphrase remains secret. It does not protect a running process that has already unlocked the key, and it does not repair an exposed passphrase. If either secret was disclosed, replace the key and update every system that trusts it.
6. Choose DER only when the consumer requires it
PEM is the default and is usually easier to inspect and transport. DER is a binary encoding. Request it explicitly when the consuming API requires DER:
$ openssl genpkey -algorithm RSA \
> -pkeyopt rsa_keygen_bits:2048 \
> -outform DER -out rsa-private.der -quiet
$ file rsa-private.der
rsa-private.der: data
Do not use head on a DER key as a human-readable check. Validate it through OpenSSL instead:
$ openssl pkey -inform DER -in rsa-private.der -check -noout
Key is valid
-outform is ignored when -genparam is used, so do not confuse a parameter file with a private-key file. The ordinary key examples here do not need -genparam or -paramfile. Those options belong to workflows where parameters are generated first, such as some DH or EC deployments.
7. Recover from common mistakes
- If OpenSSL says an option is unknown, run
openssl genpkey -helpand compare it with the local manual. Remove unsupported version-specific options rather than silently changing the algorithm. - If a destination already exists, stop and inspect it before using
-out. Redirecting or overwriting a key can destroy the only usable copy. - If a passphrase prompt or
-passsource fails, do not guess repeatedly in an automated job. Fix the secret source, then validate the resulting key withopenssl pkey -check -noout. - If the key validates but the application rejects it, check its required algorithm, curve, encoding and encryption support. A valid OpenSSL key can still be the wrong type for its consumer.
To undo this guide's test files, first confirm their exact names and that they are not used elsewhere, then remove those specific files: rsa-private.pem, rsa-public.pem, ec-private.pem, rsa-encrypted.pem, key-passphrase.txt and rsa-private.der. Deleting a private key is irreversible unless another protected copy exists.
Done means
- The installed OpenSSL version and supported
genpkeyoptions were checked. - The generated private key uses the algorithm, size or curve required by its consumer.
openssl pkey -check -nooutreportsKey is valid.- The file format is PEM unless the consumer explicitly requires DER.
- Private files and passphrase sources have restrictive permissions and are not copied into logs or repositories.