TLS and certificates

Convert between PEM, DER, and PFX

nginx wants PEM files, Windows and IIS want a PFX, and some Java and appliance tools want DER. Find out which format a file is in, convert it with openssl, and get past the OpenSSL 3 error on old PFX files.

Written againstOpenSSL 3.0 (Debian 12, Ubuntu 24.04)OpenSSL 3 (RHEL 9)Windows Server 2019, 2022, and 2025
Reading time
4 min
Commands to copy
19
Last checked
24 Oct 2026

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

FormatLooks likeHoldsUsual extensions
PEMText, starting with -----BEGINCertificates, keys, or both, one block each.pem, .crt, .cer, .key
DERBinaryOne certificate or one key.der, .cer, .crt
PKCS#12Binary, protected by a passwordA private key, its certificate, and the chain.pfx, .p12
PKCS#7Text with BEGIN PKCS7, or binaryCertificates 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:

shell
$ head -1 cert.crt-----BEGIN CERTIFICATE-----$ file cert.crtcert.crt: PEM certificate
First lineContains
BEGIN CERTIFICATEA certificate. Several of these in one file are a chain.
BEGIN PRIVATE KEYA private key in PKCS#8, RSA or EC.
BEGIN RSA PRIVATE KEYAn RSA key in the older PKCS#1 format.
BEGIN EC PRIVATE KEYAn EC key in its older format.
BEGIN ENCRYPTED PRIVATE KEYA PKCS#8 key protected by a passphrase.
BEGIN CERTIFICATE REQUESTA 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.

shell
$ 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

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

shell
$ 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.

shell
$ 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 sha1

To import on Windows from PowerShell, into the computer’s personal store:

PowerShell
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:

shell
# 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:

shell
$ cat cert.pem chain.pem > fullchain.pem

Old 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:

shell
$ 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.

shell
$ openssl pkcs12 -in old.pfx -nokeys -out cert.pem -legacy

PKCS#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:

shell
$ 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.