.key private key files

A `.key` file holds a private key, almost always PEM-encoded. The extension does not say which key format is inside, and there are four possibilities distinguished by the header line — `BEGIN PRIVATE KEY` is unencrypted PKCS#8, `BEGIN ENCRYPTED PRIVATE KEY` is PKCS#8 with a passphrase, `BEGIN RSA PRIVATE KEY` is PKCS#1 and RSA-only, and `BEGIN EC PRIVATE KEY` is SEC1 and EC-only. Read the first line before doing anything else, because it determines which tools will accept the file.

Updated August 19, 2026 Verified against OpenSSL 3.5.7

Read the header first #

head -n1 private.key
Header line Format Algorithms Encrypted
-----BEGIN PRIVATE KEY----- PKCS#8 Any No
-----BEGIN ENCRYPTED PRIVATE KEY----- PKCS#8 Any Yes
-----BEGIN RSA PRIVATE KEY----- PKCS#1 RSA only Only with a Proc-Type line
-----BEGIN EC PRIVATE KEY----- SEC1 EC only Only with a Proc-Type line
-----BEGIN OPENSSH PRIVATE KEY----- OpenSSH Any Optionally

The last row is worth calling out: an SSH key is not a TLS key. OpenSSL will not read it and no web server will accept it. If that is what you have, you are in the wrong place — you need a key generated for TLS.

Inspecting a key #

Key type, size and parameters
openssl pkey -in private.key -noout -text

For just the essentials:

openssl pkey -in private.key -noout -text | head -n2
Expected output
Private-Key: (2048 bit, 2 primes)
modulus:

Deriving the public key #

openssl pkey -in private.key -pubout -out public.pem

This is also the basis of the check that matters most in practice — whether a key belongs to a certificate:

Matching hashes mean the key and certificate are a pair
openssl pkey -in private.key -pubout | openssl sha256
openssl x509 -in certificate.crt -noout -pubkey | openssl sha256

See check whether a key matches a certificate for the full treatment, including why this is better than the older modulus comparison.

Encryption #

A key with BEGIN ENCRYPTED PRIVATE KEY needs a passphrase to use. That is more secure at rest, and it also means a web server cannot start without someone typing the passphrase — which is why production keys are usually stored unencrypted with tight file permissions instead.

Remove the passphrase
openssl pkey -in encrypted.key -out plain.key
Add one
openssl pkey -in plain.key -aes256 -out encrypted.key

Permissions #

chmod 600 private.key
chown root:root private.key

Most TLS servers read the key as root during startup and then drop privileges, so it does not need to be readable by the worker user. If a service insists otherwise, that is worth questioning.

Converting between key formats #

From To Command
PKCS#1 PKCS#8 openssl pkcs8 -topk8 -nocrypt
PKCS#8 PKCS#1 openssl rsa -traditional
PEM DER openssl pkey -outform der
Any PKCS#12 with its certificate openssl pkcs12 -export

Frequently asked questions

How do I know which key format I have?
Read the first line with head -n1 private.key. The four possible headers each name a different format, and the difference determines which libraries can load the file.
Is a .key file encrypted?
Only if the header says BEGIN ENCRYPTED PRIVATE KEY, or an older file carries a Proc-Type: 4,ENCRYPTED line beneath the header. Otherwise the key is in the clear and file permissions are the only protection it has.
Can I recover a public key from a private key?
Yes, always. openssl pkey -in private.key -pubout -out public.pem derives it. The reverse is not possible, which is the entire point.
What permissions should a key file have?
chmod 600 and ownership by the user the service runs as. nginx and Apache read the key as root before dropping privileges, so the key does not need to be readable by the worker user.

References