Convert Private Keys to Safe PKCS#8 Files with OpenSSL
You will convert an existing PEM private key into an encrypted PKCS#8 file, check that it can be read back, and understand when -nocrypt, -traditional and DER output change the result. The commands below were checked with OpenSSL 3.6.1, released on 27 January 2026.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes. You need OpenSSL and an existing private key. This guide reads and writes key files, so work on a copy until the final output has been inspected. Private keys are credentials: keep them out of shell history, logs, chat and shared temporary directories.
1. Check the installed command
Confirm the binary and version before relying on option behaviour. This is an ordinary read-only check and does not need elevated privileges:
$ command -v openssl
/usr/bin/openssl
$ openssl version
OpenSSL 3.6.1 27 Jan 2026 (Library: OpenSSL 3.6.1 27 Jan 2026)
Your path and version may differ. The important boundary is that openssl pkcs8 converts private-key containers; it does not generate a key, install a certificate or change a service configuration.
Checkpoint: make sure the input path is the key you intend to convert. Do not overwrite it in place. The command can use the same input and output path, but OpenSSL truncates the output before writing and file I/O is not atomic.
2. Create an encrypted PKCS#8 PEM file
Use -topk8 when the input is an ordinary private key and the desired output is PKCS#8. This example writes a new encrypted PEM file:
$ openssl pkcs8 \
-in key.pem \
-topk8 \
-out key-pkcs8.pem \
-iter 1000000
Because -passout is absent, OpenSSL prompts for the output passphrase without displaying it. The result uses PKCS#5 v2.0 with AES-256 and HMAC-SHA256 by default. -iter 1000000 makes password guessing more expensive, at the cost of more work whenever the file is opened.
For unattended use, choose the password source deliberately. A file descriptor, environment variable or protected file may be more appropriate than putting a password directly in the command line. For a quick local test only, the syntax is:
$ openssl pkcs8 -in key.pem -topk8 -out key-pkcs8.pem \
-iter 1000000 -passout pass:REPLACE_WITH_A_TEST_PASSWORD
Do not use a real production password in that form. It can be visible to process inspection or saved in shell history. Replace the test output if the passphrase has been exposed:
$ openssl pkcs8 -in key-pkcs8.pem -passin pass:REPLACE_WITH_A_TEST_PASSWORD \
-out /tmp/key-recovered.pem
Checkpoint: an encrypted PEM file starts with -----BEGIN ENCRYPTED PRIVATE KEY-----. Seeing that header confirms the container is encrypted, but it does not prove that the password is strong or that the intended key is inside.
3. Verify the conversion without printing the key
Reading the converted file back is a useful smoke test. OpenSSL will prompt for the password if -passin is omitted:
$ openssl pkcs8 -in key-pkcs8.pem -out recovered-key.pem
Enter pass phrase for key-pkcs8.pem:
To compare the key material without displaying private bytes, derive a public key from both files and compare those public files. The first command reads the original unencrypted key; the second reads the PKCS#8 key and asks for its passphrase:
$ openssl pkey -in key.pem -pubout -out original-public.pem
$ openssl pkey -in key-pkcs8.pem -passin pass:REPLACE_WITH_A_TEST_PASSWORD \
-pubout -out converted-public.pem
$ cmp original-public.pem converted-public.pem
$ printf 'public keys match\n'
public keys match
A zero exit status from cmp means the public representations are identical. If it reports a difference, stop and investigate the input path, password and conversion commands. Do not delete the original until the application that will consume the new file has also been tested.
4. Read DER input or write DER output
PEM is the default input and output format. DER is binary, so select it explicitly with -inform DER or -outform DER. For an unencrypted DER PKCS#8 file, convert it to readable PEM like this:
$ openssl pkcs8 -inform DER -nocrypt \
-in key.der -out key.pem
Use -nocrypt only when the input really is an unencrypted PKCS#8 PrivateKeyInfo. Without it, the command expects an encrypted PKCS#8 structure and will ask for a password. The option disables encryption; it is not a way to recover a forgotten password.
To produce encrypted DER PKCS#8 from an ordinary PEM key, combine -topk8 with -outform DER:
$ openssl pkcs8 -in key.pem -topk8 \
-outform DER -out key-pkcs8.der -iter 1000000
DER does not have a visible header. Verify its format by reading it back with matching options:
$ openssl pkcs8 -inform DER -in key-pkcs8.der \
-passin pass:REPLACE_WITH_A_TEST_PASSWORD -out /tmp/checked.pem
5. Handle legacy consumers carefully
Some older software accepts only a traditional RSA, DSA or EC private-key container. If you are converting from encrypted PKCS#8 to that legacy form, omit -topk8 and add -traditional:
$ openssl pkcs8 -in key-pkcs8.pem \
-passin pass:REPLACE_WITH_A_TEST_PASSWORD \
-traditional -out legacy-key.pem
This is a compatibility escape hatch, not a security improvement. Prefer encrypted PKCS#8 where the receiving program supports it. The traditional output may use a PEM encryption scheme that is less useful than modern PKCS#8 encryption, and unencrypted output is especially risky.
Do not reach for -v1 just because an old application rejects the default. PKCS#5 v1.5 and PKCS#12 algorithms exist for compatibility, but some use weak DES or RC2 variants. First check the application's exact accepted formats. If it genuinely requires a legacy algorithm, document that exception and plan its removal.
6. Avoid the dangerous shortcuts
-nocrypt writes an unencrypted PKCS#8 private key. It may be required by particular software, but anyone who can read the file can use the key. If you must create one, restrict its permissions and keep it only where the consumer requires it:
$ openssl pkcs8 -in key.pem -topk8 -nocrypt -out key-plain-pkcs8.pem
$ chmod 600 key-plain-pkcs8.pem
$ head -n 1 key-plain-pkcs8.pem
-----BEGIN PRIVATE KEY-----
There is no cryptographic undo for this choice. Replace the plaintext file with an encrypted copy when possible, then remove the exposed copy using your system's approved secure disposal process. If the plaintext key was accessible to an unintended user, treat it as compromised and rotate the key rather than assuming deletion makes the exposure disappear.
Done means
- The installed OpenSSL version and input path were checked.
-topk8produced a new encrypted PKCS#8 file without overwriting the original.- The output was read back successfully with the intended password.
- Public keys derived from the original and converted files matched.
- DER, legacy and plaintext options were used only for a stated compatibility need.
- No private key or real password was printed, logged or placed in shell history.