Convert a PKCS#1 key to PKCS#8
To convert a PKCS#1 private key to PKCS#8, run `openssl pkcs8 -topk8 -in pkcs1.key -out pkcs8.key -nocrypt`. You can tell the two apart from the header line alone — PKCS#1 reads `-----BEGIN RSA PRIVATE KEY-----` and PKCS#8 reads `-----BEGIN PRIVATE KEY-----`. PKCS#8 wraps the same key material in a structure that also records which algorithm the key belongs to, which is why it works for RSA, EC and Ed25519 alike while PKCS#1 is RSA-only. Java, Go and most modern libraries accept only PKCS#8.
The command #
openssl pkcs8 -topk8 -in pkcs1.key -out pkcs8.key -nocrypt Replace these values
| Placeholder | What to put there |
|---|---|
-topk8 | Convert to PKCS#8. Without it the subcommand converts the other way. |
-nocrypt | Write the output unencrypted. Omit to be prompted for a passphrase. |
pkcs1.key | Input starting -----BEGIN RSA PRIVATE KEY-----. |
pkcs8.key | Output starting -----BEGIN PRIVATE KEY-----. |
Telling the formats apart #
head -n1 private.key | Header line | Format | Algorithms |
|---|---|---|
-----BEGIN RSA PRIVATE KEY----- |
PKCS#1 | RSA only |
-----BEGIN EC PRIVATE KEY----- |
SEC1 | EC only |
-----BEGIN PRIVATE KEY----- |
PKCS#8, unencrypted | Any |
-----BEGIN ENCRYPTED PRIVATE KEY----- |
PKCS#8, encrypted | Any |
Producing an encrypted PKCS#8 key #
openssl pkcs8 -topk8 -in pkcs1.key -out pkcs8.key -v2 aes-256-cbc OpenSSL prompts for the passphrase. In a script, add -passout file:/run/secrets/key-password
rather than putting the secret on the command line.
Converting an EC key #
The same command works — -topk8 is not RSA-specific despite the format it usually replaces:
openssl pkcs8 -topk8 -in ec-sec1.key -out ec-pkcs8.key -nocrypt Verify the conversion #
The key must still match its certificate afterwards. Comparing public keys proves the material survived intact:
openssl pkey -in pkcs1.key -pubout | openssl sha256
openssl pkey -in pkcs8.key -pubout | openssl sha256 And confirm the header is what you expected:
head -n1 pkcs8.key Expected output
-----BEGIN PRIVATE KEY-----
If it reads BEGIN ENCRYPTED PRIVATE KEY, you left out -nocrypt and a server that cannot prompt
for a passphrase will fail to start.
Going the other way #
Frequently asked questions
- How do I tell PKCS#1 from PKCS#8 at a glance?
- The header line.
-----BEGIN RSA PRIVATE KEY-----is PKCS#1,-----BEGIN PRIVATE KEY-----is unencrypted PKCS#8, and-----BEGIN ENCRYPTED PRIVATE KEY-----is PKCS#8 with a passphrase.-----BEGIN EC PRIVATE KEY-----is the EC equivalent of PKCS#1, defined by SEC1. - Does this change the key?
- No. The same private key material is rewrapped in a different ASN.1 structure. The public key, the certificate it matches and every signature it has produced remain valid.
- Why does Java reject my key?
- Java's KeyFactory reads PKCS#8 only. A
BEGIN RSA PRIVATE KEYfile will fail to parse no matter how it is loaded, which is the single most common reason to run this conversion. - What if I want the output encrypted?
- Drop
-nocryptand OpenSSL prompts for a passphrase, producing aBEGIN ENCRYPTED PRIVATE KEYfile. Add-v2 aes-256-cbcto choose the cipher explicitly rather than accepting the default.
References
- openssl-pkcs8(1) — -topk8
- RFC 5958: asymmetric key packages — PKCS#8, the self-describing private key container