# .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.

Source: https://certguru.io/formats/key/
Last updated: 2026-08-19
Commands verified against OpenSSL 3.5.7.

---

## Read the header first

```bash
head -n1 private.key
```

| Header line | Format | Algorithms | Encrypted |
| --- | --- | --- | --- |
| `-----BEGIN PRIVATE KEY-----` | [PKCS#8](/formats/pkcs8/) | 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*

```bash
openssl pkey -in private.key -noout -text
```

For just the essentials:

```bash
openssl pkey -in private.key -noout -text | head -n2
```

Expected output:

```
Private-Key: (2048 bit, 2 primes)
modulus:
```

> **openssl pkey handles every key type**
>
> The older `openssl rsa` and `openssl ec` subcommands still work but only for their own algorithm.
>   `openssl pkey` reads all of them, so it is the one worth putting in scripts.

## Deriving the public key

```bash
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*

```bash
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](/openssl/check-key-matches-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*

```bash
openssl pkey -in encrypted.key -out plain.key
```

*Add one*

```bash
openssl pkey -in plain.key -aes256 -out encrypted.key
```

> **Handling private keys**
>
> A private key is the entire security of the certificate it belongs to. Do not email one, do not
>   paste one into a web tool, and do not commit one — including into a branch you intend to delete,
>   since it stays in the object store. If a key has been exposed, the only real remedy is to generate
>   a new one and have the certificate reissued.

## Permissions

```bash
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`](/convert/pkcs1-to-pkcs8/) |
| PKCS#8 | PKCS#1 | [`openssl rsa -traditional`](/convert/pkcs8-to-pkcs1/) |
| PEM | DER | [`openssl pkey -outform der`](/convert/pem-to-der/) |
| Any | PKCS#12 with its certificate | [`openssl pkcs12 -export`](/convert/pem-to-pfx/) |


## 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&#58; 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

- [RFC 5958: asymmetric key packages](https://www.rfc-editor.org/rfc/rfc5958) — PKCS#8, the self-describing private key container
- [RFC 5915: elliptic curve private key structure](https://www.rfc-editor.org/rfc/rfc5915) — the SEC1 EC key format

## Related pages

- https://certguru.io/formats/pkcs8/
- https://certguru.io/convert/pkcs1-to-pkcs8/
- https://certguru.io/errors/bad-decrypt/
- https://certguru.io/openssl/generate-private-key/
- https://certguru.io/openssl/remove-passphrase-from-key/
- https://certguru.io/openssl/check-key-matches-certificate/

--
CertGuru — https://certguru.io
