A certificate is the same data whatever the file looks like. The formats differ in encoding (text or binary) and in what they bundle: one certificate, a chain, or a certificate with its private key. File extensions don’t decide it: a .crt or .cer file can be PEM or DER.
The formats
| Format | Looks like | Holds | Usual extensions |
|---|---|---|---|
| PEM | Text, starting with -----BEGIN | Certificates, keys, or both, one block each | .pem, .crt, .cer, .key |
| DER | Binary | One certificate or one key | .der, .cer, .crt |
| PKCS#12 | Binary, protected by a password | A private key, its certificate, and the chain | .pfx, .p12 |
| PKCS#7 | Text with BEGIN PKCS7, or binary | Certificates only, no key | .p7b, .p7c |
Find out which one you have
A PEM file is text, so its first line says what’s in it:
$ head -1 cert.crt-----BEGIN CERTIFICATE-----$ file cert.crtcert.crt: PEM certificate
| First line | Contains |
|---|---|
BEGIN CERTIFICATE | A certificate. Several of these in one file are a chain. |
BEGIN PRIVATE KEY | A private key in PKCS#8, RSA or EC. |
BEGIN RSA PRIVATE KEY | An RSA key in the older PKCS#1 format. |
BEGIN EC PRIVATE KEY | An EC key in its older format. |
BEGIN ENCRYPTED PRIVATE KEY | A PKCS#8 key protected by a passphrase. |
BEGIN CERTIFICATE REQUEST | A CSR, not a certificate yet. |
If the first line is unreadable, the file is binary: DER or PKCS#12. Try reading it as a DER certificate. If that fails, it’s probably a PFX, which asks for a password.
$ openssl x509 -in cert.cer -inform der -noout -subjectsubject=CN = www.example.com$ openssl pkcs12 -in bundle.pfx -info -nooutEnter Import Password:
PEM and DER
# PEM to DER, and back$ openssl x509 -in cert.pem -outform der -out cert.der$ openssl x509 -in cert.der -inform der -out cert.pem# the same for a key$ openssl pkey -in key.pem -outform der -out key.der
PEM to PFX for Windows
IIS and the Windows certificate store take the key, the certificate, and the chain in one PFX file. -certfile adds the intermediates, and -name is the friendly name Windows shows.
$ openssl pkcs12 -export -inkey key.pem -in cert.pem -certfile chain.pem -name www.example.com -out www.example.com.pfxEnter Export Password:Verifying - Enter Export Password:
OpenSSL 3 encrypts the file with AES-256 by default. Windows Server 2019 and later import that. Windows Server 2016 and older Java 8 runtimes don’t: export for them with the older algorithms instead.
$ openssl pkcs12 -export -inkey key.pem -in cert.pem -certfile chain.pem -name www.example.com -out www.example.com.pfx -certpbe PBE-SHA1-3DES -keypbe PBE-SHA1-3DES -macalg sha1To import on Windows from PowerShell, into the computer’s personal store:
PS> $password = Read-Host -AsSecureString -Prompt 'PFX password'PS> Import-PfxCertificate -FilePath .\www.example.com.pfx -CertStoreLocation Cert:\LocalMachine\My -Password $password
PFX to PEM for nginx
Take the file apart into the pieces a Linux service asks for:
# the server certificate only$ openssl pkcs12 -in www.example.com.pfx -clcerts -nokeys -out cert.pem# the intermediates$ openssl pkcs12 -in www.example.com.pfx -cacerts -nokeys -out chain.pem# the private key, without a passphrase$ openssl pkcs12 -in www.example.com.pfx -nocerts -noenc -out key.pem$ chmod 600 key.pem
-noenc is the OpenSSL 3 name for what older guides call -nodes. Both work in 3.0. For nginx, put the server certificate first and the intermediates after it in one file:
$ cat cert.pem chain.pem > fullchain.pemOld PFX files and OpenSSL 3
PFX files exported by older Windows and Java versions, and by OpenSSL 1.1, encrypt the certificates with RC2-40-CBC. OpenSSL 3 moved that algorithm to the legacy provider, which isn’t loaded by default, so reading such a file fails:
$ openssl pkcs12 -in old.pfx -nokeys -out cert.pemEnter Import Password:Error outputting keys and certificates40F7B1D3E07F0000:error:0308010C:digital envelope routines:inner_evp_generic_fetch:unsupported:...:Algorithm (RC2-40-CBC : 0), Properties ()# the error line is shortened
Add -legacy to load it for that command. The file itself is fine, and the converted PEM files work with OpenSSL 3 as they are.
$ openssl pkcs12 -in old.pfx -nokeys -out cert.pem -legacyPKCS#7 chains
Windows and some CAs hand out the chain as a .p7b file, with certificates and no key. Turn it into a PEM chain:
$ openssl pkcs7 -in chain.p7b -print_certs -out chain.pem# for a binary .p7b, add -inform der
Last checked on 24 October 2026 against OpenSSL 3.0 (Debian 12, Ubuntu 24.04), OpenSSL 3 (RHEL 9), and Windows Server 2019, 2022, and 2025. If a step doesn’t match what you see, contact us with the command and what it printed.