Safely Inspect and Convert RSA Keys with openssl rsa
Hand someone a private key file and the first question is always whether it is intact, and openssl rsa answers that in one command. That first check is read-only, and you will finish with a checked RSA private key, a separate public key, and repeatable commands for moving between PEM and DER. The examples use OpenSSL 3.6.1, installed from the openssl package. Allow about fifteen minutes if the key files already exist.
The route
Jump straight to the step you need, or tick off Done means at the end.
You need a shell and read access to the source key. No command here needs elevated privileges unless the key itself is protected by file permissions. Work on copies or write to new filenames throughout: openssl rsa will happily write an unencrypted private key when no encryption option is given, and it will not stop you choosing a weak output location. Keep the source file until the new one has been checked and any dependent service has been tested.
1. Check the private key before changing it
Set a shell variable to the real path of your key, then ask OpenSSL to check its internal RSA consistency without printing the key itself:
key=/path/to/private-key.pem
openssl rsa -in "$key" -check -noout
An intact private key prints:
RSA key ok
An encrypted key triggers a pass phrase prompt. If the file is not PEM, name the input format explicitly with -inform DER, -inform P12 or whatever else your installed build supports; do not guess from the filename extension. OpenSSL reads standard input when -in is omitted, which makes an accidental paste or pipeline harder to review than it should be.
Checkpoint
Stop here if the check fails. Confirm the path, input format and pass phrase first. Do not overwrite the original while trying different options.
2. Export a public key into a new file
Extract the public half of the private key with -pubout:
openssl rsa -in "$key" -pubout -out public-key.pem
On OpenSSL 3.6.1, a successful run writes a PEM public key beginning with:
-----BEGIN PUBLIC KEY-----
Confirm the result actually reads back as a public key:
openssl rsa -pubin -in public-key.pem -text -noout
-pubin matters the moment the input is public-only; without it the command assumes a private key by default. -text output includes key components, so keep it out of logs and support tickets. Add -noout when you want the readable details without another encoded key block underneath.
3. Convert PEM to DER without replacing the source
PEM is text wrapped in base64. DER is binary. Write the converted key to a different path:
openssl rsa -in "$key" -outform DER -out private-key.der
Confirm the binary file reads back correctly by declaring its format explicitly:
openssl rsa -inform DER -in private-key.der -check -noout
Expect RSA key ok again. DER output is no good in a text editor or a PEM-only configuration field, and a PEM output file is the default whenever -outform is left out. If another program insists on the traditional PKCS#1 private-key wrapper rather than the OpenSSL 3 default PKCS#8 wrapper, add -traditional while writing a private PEM file, but confirm the receiving program actually needs it first.
4. Add or change private-key encryption
To create an encrypted PEM copy, choose a cipher such as AES-256:
openssl rsa -in "$key" -aes256 -out private-key-encrypted.pem
OpenSSL prompts for the new pass phrase without echoing it, and writes a PEM file that opens with an encrypted private-key heading. Check the result by supplying the pass phrase interactively:
openssl rsa -in private-key-encrypted.pem -check -noout
To automate a non-interactive check, use a password source appropriate to your secret-management system with -passin, which accepts sources such as a file or an environment variable. Keep a real pass phrase out of a shell command directly: it can end up in shell history, process listings or CI logs. The same applies to -passout when creating encrypted output.
Warning
Omit every encryption option and you get a plain-text private key. That is how the command removes a pass phrase, but it also creates a copy that anyone who can read the file can use. If you genuinely need that form, lock down its permissions, test the consumer, and securely remove the unencrypted copy once the replacement is confirmed working. Do not use sudo to make a key readable unless the service's ownership and permissions actually require it.
5. Diagnose the common format and output mistakes
- Pass phrase errors: rerun the read-only
-checkcommand and confirm you are using-passinfor the input key, not-passoutfor the new file. - Public key rejected: add
-pubinwhen reading a public PEM. Reserve-RSAPublicKey_infor the older RSAPublicKey structure, which differs from the usual SubjectPublicKeyInfo output that-puboutproduces. - Binary output looks corrupt: that is normal for DER. Read it back with
-inform DER; do not open it in an editor or paste it into a text configuration file. - Output is unexpectedly plain text: encryption is opt-in for this command. Recreate the output with
-aes256or another permitted cipher, then verify it before replacing any consumer's key. - The output file already exists: choose a new temporary name, compare and check it, then arrange the service's changeover. Never set the output filename equal to the input filename; the manpage explicitly warns against it.
-modulus prints the RSA modulus, useful for comparing whether two RSA keys belong together, but treat the resulting value as sensitive operational data. The deprecated -engine option has no place in a new setup; OpenSSL documents it as deprecated since version 3.0. The newer openssl pkey command can perform these operations for RSA and other public-key types, but use whichever command matches the surrounding procedure and its format expectations.
Done means
- The source private key passed
openssl rsa -check -noout. - The public key was exported to a different file and read back with
-pubin. - Any PEM to DER conversion was checked with the matching
-inform DERoption. - Encrypted output was tested with its pass phrase before any service change.
- No source key was overwritten, and any plain-text private-key copy has a deliberate owner, permission and removal plan.