# PEM

A PEM file is Base64-encoded binary data wrapped in `-----BEGIN <label>-----` and `-----END <label>-----` lines. It is a text container, not a data type — the label on the BEGIN line is what tells you whether the file holds a certificate, a private key, a certificate signing request or something else. Because the delimiters mark where each object starts and ends, one PEM file can hold many objects, which is why certificate chains are distributed this way and why a `.pem` extension alone tells you almost nothing about the contents.

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

---

## What is actually in the file

A PEM file is three things stacked together: a label line, Base64 text, and a closing line.

*The structure*

```text
-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
...
-----END CERTIFICATE-----
```

Base64-decode the middle and you get DER — the raw binary ASN.1 encoding. That is the entire
relationship between the two formats: **PEM is DER in Base64 with a label**.

## The label is the important part

Everything you need to know about a PEM file is on its first line:

| BEGIN line | Contents | Command that reads it |
| --- | --- | --- |
| `CERTIFICATE` | An X.509 certificate | `openssl x509` |
| `CERTIFICATE REQUEST` | A CSR | `openssl req` |
| `PRIVATE KEY` | PKCS#8 key, any algorithm | `openssl pkey` |
| `ENCRYPTED PRIVATE KEY` | PKCS#8 key with a passphrase | `openssl pkey` |
| `RSA PRIVATE KEY` | PKCS#1 key, RSA only | `openssl rsa` |
| `EC PRIVATE KEY` | SEC1 key, EC only | `openssl ec` |
| `PUBLIC KEY` | SubjectPublicKeyInfo | `openssl pkey -pubin` |
| `PKCS7` | A certificate bundle | `openssl pkcs7` |
| `X509 CRL` | A revocation list | `openssl crl` |
| `DH PARAMETERS` | Diffie-Hellman parameters | `openssl dhparam` |

```bash
head -n1 mystery.pem
```

## Several objects in one file

This is PEM's real advantage over DER, and the reason chains are distributed as PEM. The delimiters
make concatenation unambiguous:

*A chain file*

```text
-----BEGIN CERTIFICATE-----
(your server certificate)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
(the intermediate CA)
-----END CERTIFICATE-----
```

Building one is just concatenation, leaf first:

```bash
cat certificate.crt intermediate.crt > fullchain.crt
```

Counting what is in a file you were handed:

```bash
grep -c "BEGIN CERTIFICATE" fullchain.crt
```

Expected output:

```
2
```

> **Order is not enforced**
>
> Nothing about the format requires a chain to be in the right order — that is a convention servers
>   rely on, not a rule PEM enforces. A file assembled in the wrong order looks perfectly valid and
>   fails on a subset of clients. See [certificate chains](/concepts/certificate-chain/).

## Why the extension tells you so little

`.pem`, `.crt`, `.cer` and `.key` are all commonly PEM-encoded, and `.crt` and `.cer` are commonly
DER-encoded too. The extension records what someone intended the file *for*, not how it is encoded.

*Ask the file, not the name*

```bash
file mystery.crt
```

Expected output:

```
mystery.crt: PEM certificate
```

See [.crt and .cer files](/formats/crt-cer/) for the full picture.

## Reading a PEM file

*Human-readable dump of a certificate*

```bash
openssl x509 -in certificate.pem -noout -text
```

*Just the essentials*

```bash
openssl x509 -in certificate.pem -noout -subject -issuer -dates
```

## When you need something else

| Situation | Format to use |
| --- | --- |
| Certificate and key in one password-protected file | [PKCS#12](/formats/pkcs12-pfx-p12/) |
| A chain for Windows or Java tooling, no key | [PKCS#7](/formats/pkcs7-p7b/) |
| A Java application's own identity | [JKS](/formats/jks-keystore/) or PKCS#12 |
| Smallest possible binary, single object | [DER](/formats/der/) |


## Frequently asked questions

### What does PEM stand for?

Privacy-Enhanced Mail, a 1990s email encryption standard that failed to see adoption. The standard is long dead but its Base64 armouring convention outlived it and became the default way to move certificates and keys as text.

### Can one PEM file hold both a certificate and its private key?

Yes. The BEGIN and END lines delimit each object, so a file can contain a certificate followed by a key and both are parseable. HAProxy expects exactly this. nginx and Apache do not — they want separate files.

### Is a .pem file always a certificate?

No. The extension names the encoding, not the contents. Read the BEGIN line to find out what is actually in the file.

### Why does my PEM file have extra text above the certificate?

Some tools write human-readable metadata — subject and issuer lines, or PKCS#12 bag attributes — outside the BEGIN/END markers. Parsers ignore anything outside the delimiters, so the file still works. Re-emit it through `openssl x509` if you want it clean.


## References

- [RFC 7468: textual encodings of PKIX structures](https://www.rfc-editor.org/rfc/rfc7468) — defines the PEM armour and what may sit between the BEGIN and END lines
- [RFC 5280: X.509 and CRL profile](https://www.rfc-editor.org/rfc/rfc5280) — the specification every field on a certificate comes from

## Related pages

- https://certguru.io/formats/der/
- https://certguru.io/formats/crt-cer/
- https://certguru.io/convert/pem-to-der/
- https://certguru.io/convert/pem-to-pfx/
- https://certguru.io/formats/key/

--
CertGuru — https://certguru.io
