Most guides to certificate file formats are organized the wrong way. They list the extensions (.cer, .crt, .pem, .der, .pfx) and describe each one as if the extension determined the format. It does not.
The foundational truth about certificate files: there are two binary encodings (PEM and DER) and a small number of container formats (PKCS#12, PKCS#7). Extensions like .cer, .crt, .pem, and .der are naming conventions applied inconsistently across platforms and tools. A file named certificate.cer might be PEM-encoded text. It might be DER-encoded binary. The name tells you nothing definitive. Two files named differently can be byte-for-byte identical.
Understanding the two encodings first, then understanding extensions as unreliable labels for those encodings, unlocks all the confusion. This guide is structured that way: encodings first, extensions second, identification third, conversion fourth.
The Two Encodings: PEM and DER
Every X.509 certificate and private key exists as binary data structured according to ASN.1 (Abstract Syntax Notation One). The question is only how that binary data is stored on disk.
DER: the binary encoding
DER (Distinguished Encoding Rules) is the canonical binary encoding of ASN.1 data. A DER certificate file contains the raw binary bytes of the certificate. Nothing more. Opening a DER file in a text editor shows garbled characters or binary garbage because it is not text.
DER is the root format. All other certificate encodings are transformations of DER data. When a Certificate Authority issues a certificate, the underlying object is DER.
DER files are compact and unambiguous. A DER file contains exactly one certificate or one private key. It cannot contain multiple objects concatenated. DER is the preferred format in Java environments and in some embedded and device contexts.
PEM: DER wrapped in Base64 text
PEM (Privacy-Enhanced Mail) is DER data encoded in Base64 and wrapped in header and footer lines. The header and footer identify what type of object is encoded: —–BEGIN CERTIFICATE—–, —–BEGIN PRIVATE KEY—–, —–BEGIN RSA PRIVATE KEY—–, and so on.
The Base64 encoding makes PEM files ASCII text, readable in a text editor and safe to copy-paste, embed in configuration files, and transmit over text-based protocols. This is why PEM is overwhelmingly the more common format for certificate delivery and server configuration.
PEM has one capability that DER lacks: a single PEM file can contain multiple objects concatenated. A file can contain a leaf certificate, followed by an intermediate certificate, followed by a root certificate, each with its own BEGIN/END block. This is how certificate chain files and full bundle files work.
The names PEM and DER describe encodings, not containers or formats. A ‘PEM certificate’ is a certificate stored as Base64 text. A ‘DER certificate’ is the same certificate stored as binary. Converting between them does not change the cryptographic content of the certificate. The bytes are repackaged, not modified. A PEM-to-DER conversion is a Base64 decode operation; a DER-to-PEM conversion is a Base64 encode operation plus adding the headers.
The Container Formats: PKCS#12 and PKCS#7
Beyond the two encodings, two container formats bundle multiple objects together:
PKCS#12 (.pfx, .p12): the complete bundle
PKCS#12 is a binary container format (RFC 7292) that holds a certificate, its private key, and optionally intermediate and root certificates in a single password-protected file. It was originally a Microsoft standard and remains the primary format for Windows certificate import and export. IIS, Azure App Service, and most Windows certificate management tools work natively with PFX.
The password on a PFX file protects the private key and encrypts the entire bundle. The encryption algorithm used has changed across OpenSSL versions: OpenSSL 3.x changed the default from legacy 3DES/SHA1 to AES-256-CBC with SHA256. This compatibility change matters in practice: a PFX created with OpenSSL 3.x default settings may fail to import on Windows Server 2019 or earlier, older Java versions, or other systems that do not yet support the newer encryption. The fix is to export with explicit legacy parameters.
| # Create PFX with modern encryption (OpenSSL 3.x default):
$ openssl pkcs12 -export -out cert.pfx -inkey private.key -in cert.crt -certfile chain.pem
# Create PFX with legacy encryption (for compatibility with older systems): # This is required for Windows Server 2019 and earlier, older Java, some appliances $ openssl pkcs12 -export -out cert.pfx -inkey private.key -in cert.crt \ -certfile chain.pem -legacy
# The -legacy flag instructs OpenSSL 3.x to use the older 3DES/SHA1 encryption # that older systems expect. Without it, newer PFX files may fail to import. |
Never upload a PFX file to an online certificate converter. PFX files contain the private key. Any tool or service that receives your PFX also receives your private key. A leaked private key requires immediate certificate revocation and reissuance. All conversions involving PFX files should be performed locally using OpenSSL or the Windows certutil command.
PKCS#7 (.p7b, .p7c): chain without private key
PKCS#7 (RFC 2315, superseded for CMS operations by RFC 5652) is a format that contains certificates and certificate chains but never private keys. It is used primarily on Windows and IIS for importing certificate chains. A .p7b file contains the leaf certificate plus intermediates but not the private key; the server’s private key must be installed separately.
PKCS#7 files can be Base64-encoded (PEM-like, with —–BEGIN PKCS7—– header) or binary DER-encoded. The extension .p7b is typically Base64; .p7c is less common. Most administrators encounter .p7b in Windows IIS workflows.
Extensions as Unreliable Labels: What Each Typically Means
With the encodings and containers understood, extensions can be placed in their proper context as conventions rather than definitions:
| Extension | Typical meaning | Can also be | Actually determined by |
| .pem | PEM-encoded certificate, key, or chain | Rarely anything else | Opening in text editor: shows —–BEGIN … —– headers |
| .crt | PEM-encoded certificate (Linux/Unix convention) | DER-encoded certificate (less common but valid) | Opening in text editor: text = PEM; binary = DER |
| .cer | DER-encoded certificate (Windows convention) | PEM-encoded certificate (common on Windows exports too) | Opening in text editor: text = PEM; binary = DER |
| .der | DER-encoded certificate or key | Almost always actually DER | Opening in text editor: always binary garbage if truly DER |
| .key | PEM-encoded private key | DER-encoded private key | Opening in text editor: text = PEM; binary = DER |
| .pfx or .p12 | PKCS#12 binary bundle (cert + key + chain) | Always PKCS#12; extensions are interchangeable | Binary format; cannot be opened as text |
| .p7b | PKCS#7 chain (Base64) | PKCS#7 binary (.p7c) | Opening in text editor: shows —–BEGIN PKCS7—– or binary |
| .csr | PEM-encoded Certificate Signing Request | DER-encoded CSR (less common) | Opening in text editor: shows —–BEGIN CERTIFICATE REQUEST—– |
The .cer extension is commonly associated with DER encoding because Windows Certificate Manager exports DER by default when using the .cer extension. However, Windows can also export PEM-encoded files with the .cer extension. When you receive a .cer file from a CA or a Windows administrator, do not assume it is DER. Open it in a text editor to check.
How to Identify What You Actually Have
Before converting, identify the actual encoding. Opening the file in a text editor provides the definitive answer in most cases:
| What you see when opening in a text editor | What you have |
| —–BEGIN CERTIFICATE—– followed by Base64 text | PEM-encoded certificate |
| —–BEGIN PRIVATE KEY—– or —–BEGIN RSA PRIVATE KEY—– | PEM-encoded private key (PKCS#8 or traditional RSA format respectively) |
| —–BEGIN CERTIFICATE REQUEST—– | PEM-encoded CSR |
| —–BEGIN PKCS7—– | PEM-encoded PKCS#7 chain |
| Binary garbage / unreadable characters | DER-encoded certificate, key, or PKCS#12 (cannot distinguish without tools) |
| Multiple —–BEGIN CERTIFICATE—– blocks | PEM chain file containing multiple certificates concatenated |
| # Identify format using OpenSSL (try PEM first, then DER):
# Test if file is PEM-encoded certificate: $ openssl x509 -in unknown.cer -text -noout # If successful: it is a PEM certificate # If error: try DER
# Test if file is DER-encoded certificate: $ openssl x509 -in unknown.cer -inform DER -text -noout # If successful: it is a DER certificate
# Test if file is a PKCS#12 bundle: $ openssl pkcs12 -in unknown.pfx -info -noout # Will prompt for password; if it parses, it is PKCS#12
# Linux/macOS: use the ‘file’ command for a quick format hint: $ file unknown.cer # PEM files return: ‘PEM certificate’ or ‘ASCII text’ # DER files return: ‘data’ (binary) # PKCS#12 files return: ‘DER Encoded Keystore’
# Check what a PEM file contains (shows all objects in the file): $ grep ‘BEGIN’ bundle.pem # Shows all BEGIN lines, revealing how many certs/keys are in the file |
All Conversions: Complete OpenSSL Reference
PEM to DER and DER to PEM
| # PEM certificate to DER:
$ openssl x509 -in cert.pem -outform DER -out cert.der
# DER certificate to PEM: $ openssl x509 -in cert.der -inform DER -outform PEM -out cert.pem
# PEM private key to DER: $ openssl pkey -in private.key -outform DER -out private.der
# DER private key to PEM: $ openssl pkey -in private.der -inform DER -outform PEM -out private.key
# .cer to .crt (or vice versa): if both are PEM, just rename # cp cert.cer cert.crt # If one is DER and the other needs to be PEM, convert as above |
Building and splitting PEM chain files
| # Combine leaf cert + intermediate + root into a single chain PEM:
$ cat cert.pem intermediate.pem root.pem > fullchain.pem # Order matters: leaf certificate must be first
# Extract individual certificates from a chain PEM: # Open fullchain.pem in a text editor and copy each BEGIN/END block # separately into individual files. Or use awk to split: $ awk ‘BEGIN {n=0} /—–BEGIN CERTIFICATE—–/ {n++; file=”cert-” n “.pem”} {print > file}’ fullchain.pem
# Check how many certificates are in a chain file: $ grep -c ‘BEGIN CERTIFICATE’ fullchain.pem # Typical web server chain: returns 2 (leaf + intermediate) # With root included: returns 3 |
To and from PKCS#12 (PFX)
| # Create PFX from PEM cert, key, and chain (modern encryption):
$ openssl pkcs12 -export -out cert.pfx \ -inkey private.key \ -in cert.pem \ -certfile chain.pem
# Create PFX with legacy encryption (for Windows Server 2019 and older): $ openssl pkcs12 -export -out cert.pfx -legacy \ -inkey private.key -in cert.pem -certfile chain.pem
# Extract all certs from PFX to PEM (no private key): $ openssl pkcs12 -in cert.pfx -nokeys -out certs.pem
# Extract private key from PFX to PEM (unencrypted): $ openssl pkcs12 -in cert.pfx -nocerts -nodes -out private.key # WARNING: -nodes removes the key encryption; protect the output file
# Extract private key from PFX to PEM (password-protected): $ openssl pkcs12 -in cert.pfx -nocerts -out private.key
# View PFX contents without extracting: $ openssl pkcs12 -in cert.pfx -info -noout |
To and from PKCS#7 (P7B)
| # Create P7B chain from PEM certificate(s):
$ openssl crl2pkcs7 -nocrl -certfile cert.pem -certfile chain.pem -out bundle.p7b
# Extract certificates from P7B to PEM: $ openssl pkcs7 -in bundle.p7b -print_certs -out certs.pem
# If the P7B is DER-encoded (not Base64): $ openssl pkcs7 -in bundle.p7b -inform DER -print_certs -out certs.pem |
Windows certutil (alternative to OpenSSL on Windows)
| # Convert DER .cer to PEM on Windows:
> certutil -encode cert.cer cert.pem
# Convert PEM to DER on Windows: > certutil -decode cert.pem cert.der
# View certificate details from file on Windows: > certutil -dump cert.cer
# Import PFX into Windows Certificate Store: > certutil -importpfx cert.pfx
# Export from Windows Certificate Store to PFX: # Use certmgr.msc (GUI) or: > certutil -exportpfx -p password My <thumbprint> cert.pfx |
Platform-to-Format Quick Reference
The right format for each platform or tool:
| Platform / Tool | Certificate format | Key format | Chain handling |
| Nginx | PEM (.pem or .crt) | PEM (.key) | Separate chain file concatenated with cert, or fullchain.pem |
| Apache | PEM (.pem or .crt) | PEM (.key) | Separate SSLCertificateChainFile or combined in cert file |
| Windows IIS | PKCS#12 (.pfx) | Included in .pfx | Included in .pfx |
| Azure App Service / Azure CDN | PKCS#12 (.pfx) | Included in .pfx | Included in .pfx |
| Java / Tomcat | PKCS#12 (.p12) recommended (or JKS) | In the keystore | In the keystore |
| AWS ACM (import) | PEM (.pem or .crt) | PEM (.key) | Separate PEM chain field |
| Let’s Encrypt (certbot output) | PEM (fullchain.pem, cert.pem) | PEM (privkey.pem) | fullchain.pem includes chain; chain.pem is chain only |
| macOS Keychain | PKCS#12 (.p12) or DER (.cer) | In .p12 or separately | In .p12 or imported separately |
| Android / iOS (MDM) | DER (.cer) or PKCS#12 | In .p12 | In .p12 or trust store |
Frequently Asked Questions
What is the actual difference between .cer and .crt?
There is no technical difference. Both extensions typically contain a single X.509 certificate. The file contents can be either PEM (Base64 text) or DER (binary) regardless of the extension. The .crt extension is a convention on Linux/Unix systems; .cer is a convention on Windows. A file can be renamed from .cer to .crt or vice versa with no effect on its content. To determine the actual encoding, open the file in a text editor: if it shows —–BEGIN CERTIFICATE—– headers and Base64 text, it is PEM. If it shows binary garbage, it is DER.
Can I just rename a .cer file to .pem or .crt?
If the .cer file is PEM-encoded (open it in a text editor and check for the —–BEGIN CERTIFICATE—– header), renaming it to .pem or .crt is perfectly valid: the content is already PEM. If the .cer file is DER-encoded (binary garbage in a text editor), renaming it does not convert it. A DER file renamed to .pem remains DER binary data, not PEM text. The server or tool will fail to parse it. Use OpenSSL to convert DER to PEM before renaming.
Why does my PFX fail to import on Windows after converting with OpenSSL?
OpenSSL 3.x changed the default encryption algorithm for PFX files from legacy 3DES/SHA1 to AES-256-CBC/SHA256. Windows Server 2019 and earlier versions of Windows do not support the newer AES-256 encryption in PKCS#12 files. The fix is to add the -legacy flag to the openssl pkcs12 -export command when creating PFX files intended for older Windows systems. The -legacy flag tells OpenSSL 3.x to use the older encryption that those systems can process.
What is the difference between a .pem file with one certificate and a fullchain.pem?
A single-certificate PEM file contains one —–BEGIN CERTIFICATE—– block: just the leaf certificate (the one issued for your domain). A fullchain.pem contains multiple concatenated —–BEGIN CERTIFICATE—– blocks: the leaf certificate first, followed by the intermediate CA certificate, and optionally the root CA certificate. Web servers like Nginx should be configured with fullchain.pem (or the equivalent combined file) as the ssl_certificate to ensure the complete chain is sent to clients. Sending only the leaf certificate causes chain validation failures on clients that do not implement AIA fetching.
Is it safe to convert certificates using an online tool?
For conversions involving only certificates (no private key), online converters are technically safe: certificate data is public information. For any conversion involving a private key, such as extracting a key from a PFX or creating a PFX from a certificate and key pair, never use an online tool. The private key is the cryptographic secret that secures the certificate. Any online service that receives your private key has full ability to impersonate your server. Use OpenSSL locally on your own machine for all conversions involving private keys.
