.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.
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 #
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:
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.
openssl pkey -in encrypted.key -out plain.key 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 aProc-Type: 4,ENCRYPTEDline 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.pemderives it. The reverse is not possible, which is the entire point. - What permissions should a key file have?
chmod 600and 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
- RFC 5958: asymmetric key packages — PKCS#8, the self-describing private key container
- RFC 5915: elliptic curve private key structure — the SEC1 EC key format