Generate and check an RSA private key with OpenSSL genrsa
You will create a usable RSA private key, decide whether it should be encrypted at rest, and check that OpenSSL can read it. The examples take a few minutes at most, although key generation time depends on the machine and the requested size. No command here needs sudo.
The route
Jump straight to the step you need, or tick off Done means at the end.
Before you start
This guide follows the openssl-genrsa(1ssl) manual installed with the Ubuntu openssl package, version 3.0.13. Check the executable that your shell will actually run:
$ command -v openssl
$ openssl version
The command is part of OpenSSL 3. The manual says the default key size is 2048 bits, and the final positional argument, when supplied, must be at least 512 bits. Use an explicit size when a script or operational record must be unambiguous. A 2048-bit key is the sensible default for ordinary RSA compatibility; do not reduce it merely to make a test faster.
Checkpoint
You know which OpenSSL installation is being used, and you have a destination that must not be readable by other users.
1. Generate an unencrypted key
Set a restrictive umask before creating the file. The destination below is deliberately a new file in the current directory. Replace the name if your application expects a different path.
$ umask 077
$ openssl genrsa -out ./server-rsa-key.pem 2048
With this installation, a successful run is quiet when -verbose is not used. The resulting file is private key material. Do not paste it into a ticket, commit it to version control, or place it in a directory served by a web server.
OpenSSL 3 writes PKCS#8 PEM by default. The first line should therefore be:
$ sed -n '1p' ./server-rsa-key.pem
-----BEGIN PRIVATE KEY-----
2. Verify the key without printing it
Use openssl pkey to parse and check the generated key. The command below prints a short result rather than the key contents:
$ openssl pkey -in ./server-rsa-key.pem -check -noout
Key is valid
If this fails, stop and investigate the path, permissions, and whether the file was truncated. Do not overwrite it with a second generation command until you know which copy is needed. A failed or interrupted generation can leave an incomplete destination, so remove that incomplete file only after confirming it is not the last usable copy.
3. Encrypt the private key at rest
An unencrypted key is convenient for a service that must start without human input, but anyone who can read the file can use it. For a key stored offline or handled by an operator, encrypt it with a passphrase. -aes256 selects the cipher and -passout selects where the passphrase comes from.
For an interactive command, omit -passout and answer the prompt. For a repeatable example, create a temporary passphrase file with restrictive permissions:
$ umask 077
$ printf '%s\n' 'replace-this-with-a-long-unique-passphrase' > ./key-passphrase
$ openssl genrsa -aes256 \
-passout file:./key-passphrase \
-out ./server-rsa-key-encrypted.pem 2048
The passphrase file is itself a secret and must be protected. A passphrase written literally on a command line can be exposed through shell history or process inspection, so prefer a prompt or a protected file in automation. Delete the example passphrase file securely according to your organisation's handling rules after you have moved the secret to its proper secret store. Deleting it does not make a lost passphrase recoverable.
Check the encrypted key by supplying the same passphrase source:
$ openssl pkey -in ./server-rsa-key-encrypted.pem \
-passin file:./key-passphrase -check -noout
Key is valid
4. Use the traditional RSA format only when required
Some older software expects PKCS#1 PEM rather than the OpenSSL 3 default PKCS#8 PEM. Add -traditional only for that compatibility boundary:
$ openssl genrsa -traditional -out ./legacy-rsa-key.pem 2048
$ sed -n '1p' ./legacy-rsa-key.pem
-----BEGIN RSA PRIVATE KEY-----
$ openssl rsa -in ./legacy-rsa-key.pem -check -noout
RSA key ok
Do not infer the format from the filename. Check the PEM header or use the consumer's documented format requirement. If the older application can accept PKCS#8, keep the default instead.
Common traps
- Accidental overwrite:
-outwrites the destination. Choose a new name first, and make a backup before replacing an existing key. Never replace a live service key casually; changing it can break certificate matching or prevent the service starting. - Wrong executable: a machine can have more than one OpenSSL installation. Compare
command -v openssl,openssl version, and the manual you read. - Deprecated options:
-3selects public exponent 3 and is deprecated. The default exponent is 65537, selected explicitly by-F4or-f4if needed. - Unexpected progress:
-verboseprints extra generation details. Prime generation is random, so duration varies. A dot, plus, or asterisk in progress output is not key material. - Unnecessary privilege: generate in a directory you own, then arrange deployment permissions separately. Running key generation as root makes ownership and recovery harder.
Done means
- The intended OpenSSL version generated the key at the intended path.
- The key has restrictive file permissions and is not in source control or a public directory.
openssl pkey -check -noout, oropenssl rsa -check -nooutfor traditional output, reports a valid key.- Encryption, passphrase storage, and PKCS#1 compatibility were deliberate decisions, not defaults discovered after deployment.
- Any old key remains available until its replacement has been tested by the service that will use it.