Appendix
File formats: PEM, DER, PKCS #12 and friends
In one sentence
The formats are wrappings of the same data: DER is binary, PEM is DER in Base64, PKCS #12 bundles a key with its certificates, and PKCS #7 carries certificates only.
Who is this for
Level: Practitioner
On this page
A certificate is one fixed structure defined in RFC 5280. The file formats below are only different ways of storing or packing it, sometimes together with a private key or other certificates. Once you know which wrapping you have, converting is one command.
What is the actual data inside?
Certificates, CSRs, CRLs and keys are described in ASN.1 and stored as bytes using DER, the Distinguished Encoding Rules. DER always gives exactly one byte sequence for a given value, which matters because a signature is computed over those exact bytes. A DER certificate usually starts with the bytes 30 82: an ASN.1 SEQUENCE followed by a two-byte length.
od -An -tx1 -N4 cert.der
30 82 01 b2
What are the main formats?
| Format | Encoding | What it holds | Typical extensions | Where you meet it |
|---|---|---|---|---|
| DER | Binary | One certificate, CSR, CRL or key | .der, .cer, .crt |
Windows, Java, embedded devices |
| PEM | Text: Base64 of DER between -----BEGIN …----- and -----END …----- lines |
One or more objects, each with a label | .pem, .crt, .cer, .key, .csr |
OpenSSL, nginx, Apache, Linux, Kubernetes secrets |
| PKCS #12 (PFX) | Binary, password-protected | A private key plus its certificate and chain | .p12, .pfx |
Windows and IIS import and export, Java keystores, cloud services |
| PKCS #7 (P7B) | Binary or PEM | Certificates (and CRLs) only, no private key | .p7b, .p7c |
Windows chain exports, some CAs’ downloads |
| PKCS #8 | Usually PEM | One private key, optionally encrypted | .key, .pem |
Any modern library |
| PKCS #10 | Usually PEM | A certificate signing request | .csr, .req |
Requests sent to a CA |
| JKS | Binary, Java only | Keys and trusted certificates | .jks, .keystore |
Older Java applications |
PEM: DER with a label
RFC 7468 standardises the PEM labels. The label tells you what is inside:
| PEM label | What it contains | Defined in |
|---|---|---|
CERTIFICATE |
An X.509 certificate | RFC 5280 |
X509 CRL |
A certificate revocation list | RFC 5280 |
CERTIFICATE REQUEST |
A PKCS #10 CSR | RFC 2986 |
PKCS7 and CMS |
A PKCS #7 or CMS structure, such as a certificate bundle | RFC 2315, RFC 5652 |
PRIVATE KEY |
An unencrypted PKCS #8 private key | RFC 5208, RFC 5958 |
ENCRYPTED PRIVATE KEY |
A password-protected PKCS #8 private key | RFC 5958 |
PUBLIC KEY |
A public key on its own (SubjectPublicKeyInfo) | RFC 5280 |
You will also see labels outside that list. RSA PRIVATE KEY and EC PRIVATE KEY are older “traditional” key formats (PKCS #1 for RSA, SEC 1 for elliptic curves) that OpenSSL still reads and can still write:
openssl genrsa -out rsa.key 2048 && head -1 rsa.key
openssl genrsa -traditional -out rsa-old.key 2048 && head -1 rsa-old.key
-----BEGIN PRIVATE KEY-----
-----BEGIN RSA PRIVATE KEY-----
A PEM file can hold several objects one after another. A “full chain” file is the server certificate first, then each intermediate in order. Leave the root out: the client must already have it. RFC 7468 also allows text before the BEGIN line, which is why some tools write “Bag Attributes” lines there; most software ignores them.
PKCS #12 and PFX: the identity in one file
RFC 7292 defines PKCS #12. PFX is the older name for the same format; Windows still uses the .pfx extension. A PKCS #12 file can hold a private key, its certificate, the chain and a friendly name, all protected by a password. That makes it the usual way to move a server identity between systems, and also the file to guard most carefully.
openssl pkcs12 -in bundle.p12 -info -noout -passin pass:changeit
MAC: sha256, Iteration 2048
MAC length: 32, salt length: 8
PKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC, Iteration 2048, PRF hmacWithSHA256
Certificate bag
PKCS7 Data
Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 2048, PRF hmacWithSHA256
“Certificate bag” and “Shrouded Keybag” are the certificate and the encrypted private key. OpenSSL 3 protects both with AES-256 by default. Some older systems only open the legacy format, which -legacy produces; it protects the certificates with 40-bit RC2, which is weak, so use it only when you have no choice.
PKCS #7 and P7B: certificates without a key
A .p7b file is a PKCS #7 (or CMS, RFC 5652) SignedData structure that carries certificates but no signature and no key. It is a convenient way to ship a whole chain. To use it with OpenSSL-based software, unpack it into PEM certificates:
openssl pkcs7 -in bundle.p7b -print_certs -noout
subject=CN=www.example.com
issuer=CN=www.example.com
Add -inform DER if the file is binary, and replace -noout with -out certs.pem to write the certificates out.
Java keystores: JKS and PKCS #12
Java stores keys and trusted certificates in a keystore. The old Java-only format is JKS. Since JDK 9 the default keystore type is PKCS #12, the same standard format as above, so a .p12 file from OpenSSL can be used directly as a Java keystore. Each entry has an alias and is either a PrivateKeyEntry (a key with its certificate chain) or a trustedCertEntry (a CA certificate to trust). keytool itself recommends moving away from JKS; the cheat sheet has the conversion command and its warning text.
What do the file extensions mean?
Less than you would hope. An extension is a convention, not a promise:
.crtand.cerusually hold one certificate, but it can be PEM or DER. Windows’ certificate export offers both “DER encoded binary” and “Base-64 encoded” under the same.cerextension..pemsays the file is text withBEGINlines. It can hold certificates, keys or both..keyusually holds a PEM private key, encrypted or not..p12and.pfxare the same format..p7band.p7chold certificate bundles without keys.
So look inside instead. If the first line starts with -----BEGIN, it is PEM, and the label tells you the rest. If not, it is binary: try openssl x509 -inform DER, then openssl pkcs12 -info, then openssl pkcs7 -inform DER. On Linux and in Git Bash, file often recognises certificates:
file -b cert.pem cert.der req.csr
PEM certificate
Certificate, Version=3
PEM certificate request
Do not trust file blindly for keys: it can mislabel a PEM private key. The BEGIN line is more reliable.
How do I convert between them?
| From | To | Command |
|---|---|---|
| PEM certificate | DER | openssl x509 -in cert.pem -outform DER -out cert.der |
| DER certificate | PEM | openssl x509 -in cert.der -inform DER -out cert.pem |
| PEM key + certificate + chain | PKCS #12 | openssl pkcs12 -export -in cert.pem -inkey key.pem -certfile chain.pem -out bundle.p12 |
| PKCS #12 | PEM certificates | openssl pkcs12 -in bundle.p12 -nokeys -out certs.pem |
| PKCS #12 | PEM key | openssl pkcs12 -in bundle.p12 -nocerts -noenc -out key.pem |
| PKCS #7 / P7B | PEM certificates | openssl pkcs7 -in bundle.p7b -print_certs -out certs.pem |
| PEM certificates | PKCS #7 / P7B | openssl crl2pkcs7 -nocrl -certfile certs.pem -out bundle.p7b |
| Traditional RSA or EC key | PKCS #8 | openssl pkey -in old.key -out key.pem |
| PKCS #8 key | Encrypted PKCS #8 | openssl pkey -in key.pem -aes256 -out key-enc.pem |
| Private key | Its public key | openssl pkey -in key.pem -pubout -out pub.pem |
| DER | Base64 (Windows) | certutil -encode cert.der cert-b64.cer |
| JKS | PKCS #12 | keytool -importkeystore -srckeystore old.jks -destkeystore new.p12 -deststoretype PKCS12 |
Every command in this table was run for this page. -noenc writes an unencrypted key, so protect the result (chmod 600 on Linux) and delete copies you no longer need.
Paste any PEM certificate into the decoder to see the fields inside it:
Go deeper
- RFC 7468: the PEM textual encodings and their labels.
- RFC 7292: PKCS #12, the personal information exchange format.
- RFC 5958: asymmetric key packages, the successor to the PKCS #8 definition in RFC 5208.
- RFC 5652: the Cryptographic Message Syntax, the modern form of PKCS #7.
- OpenSSL
pkcs12manual and Javakeytooldocumentation: every option for building and reading keystores. - Chapter 8 explains the fields inside every certificate, whatever its wrapping.
Early edition. Checked against the standards; an independent expert review is in progress. Found a mistake? Tell us.