Decoding a certificate somebody emailed you
A client forwards an archive from whoever handles their certificates. Inside are five files: cert.crt, ca-bundle.crt, domain.cer, private.key, and something called chain.p7b. There is no note. Two of them may be the same certificate in different encodings, and one of them may not be a certificate at all.
Reading a certificate on the wire is a solved problem. Reading a certificate as a file, before it is installed anywhere, is a different exercise and it starts with working out what you have been sent.
The extension tells you nothing
There are two encodings and several containers, and the file names people use for them do not map onto either.
| What it is | Usually named | Contains |
|---|---|---|
| PEM: base64 text with BEGIN and END lines | .pem, .crt, .cer, .key | One or more of anything |
| DER: the same structure, binary | .der, .crt, .cer | Exactly one object |
| PKCS#7 | .p7b, .p7c | Certificates only. Never a private key. |
| PKCS#12 | .pfx, .p12 | Certificate, chain and private key, encrypted with a password |
Note the collisions. .crt and .cer appear in three rows, so the extension is a hint about intent and not a statement of fact. Windows tooling produces .cer for both encodings, which is where most of the confusion originates.
Identifying a file in one line
head -1 mystery.crt
If it starts with five dashes and the word BEGIN, it is PEM and the rest of that line says what it holds: CERTIFICATE, CERTIFICATE REQUEST, PRIVATE KEY, ENCRYPTED PRIVATE KEY, or RSA PRIVATE KEY. If it is binary, it is DER or one of the containers, and file will usually name it.
A PEM file can hold several objects concatenated. Count them before assuming:
grep -c 'BEGIN CERTIFICATE' bundle.crt
Three is a leaf plus two intermediates. One in a file called ca-bundle means somebody sent you a single intermediate and called it a bundle, which is fine and worth knowing.
And to read a DER file without converting it first, tell openssl the input format:
openssl x509 -inform der -in domain.cer -noout -subject -dates
The four conversions
# DER to PEM
openssl x509 -inform der -in cert.der -out cert.pem
# PEM to DER
openssl x509 -in cert.pem -outform der -out cert.der
# PKCS#7 to a PEM bundle
openssl pkcs7 -print_certs -in chain.p7b -out chain.pem
# PKCS#12 split into its parts
openssl pkcs12 -in bundle.pfx -nokeys -out certs.pem
openssl pkcs12 -in bundle.pfx -nocerts -nodes -out key.pem
The -nodes on that last line writes the private key unencrypted, which is what most servers want and is also a file you have just created in a directory that may be backed up, synchronised or in a repository. Deal with it in the same minute you create it.
Proving the key belongs to the certificate
This is the check worth learning by heart, because a mismatched pair is the single most common reason a certificate installation fails, and the error messages are uninformative in every server.
The old advice compares the RSA modulus. It works and it only works for RSA. Comparing the public key covers both RSA and elliptic curve, which matters now that a good share of certificates are the latter:
openssl x509 -in cert.pem -noout -pubkey | openssl sha256
openssl pkey -in key.pem -pubout | openssl sha256
Identical output means they are a pair. Different output means you have been sent the key for a different certificate, which happens whenever a certificate has been reissued and only half the files were updated.
The same trick answers the other question in the same family, which is whether a certificate you received corresponds to the request you sent:
openssl req -in request.csr -noout -pubkey | openssl sha256
Assembling the chain, in the order servers expect
Most servers want one file containing the leaf first, then each intermediate in order towards the root, and no root at all. The root is already in the client's trust store; sending it costs bytes on every handshake and proves nothing.
cat cert.pem intermediate.pem > fullchain.pem
Order is not cosmetic. Some servers and clients tolerate a shuffled chain and some do not, which produces the familiar situation where a site works in one browser and fails in a payment provider's callback. Verify the assembled file rather than trusting the concatenation:
openssl verify -untrusted intermediate.pem cert.pem
What that does not tell you is whether the server is actually presenting the file you built, which is a different question asked in a different way: what this server is handing out right now.
Five things to check before you install it
Two minutes, and it saves the deployment that has to be rolled back at nine in the morning.
openssl x509 -in cert.pem -noout -dates -ext subjectAltName,extendedKeyUsage,basicConstraints
The dates. Both of them. A certificate not yet valid is as broken as an expired one, and it is far more confusing.
The names. Every hostname the site answers on has to be in the alternative name list, including the apex if the list has a wildcard.
The purpose. Server authentication must be present.
The chain. You have the intermediate, and it verifies.
The key. The public key comparison above matches.
What each of those fields actually governs, and the two extensions that can disqualify a certificate that looks perfect, is in the six fields that decide whether TLS works.
The file that should not be in your inbox
A private key was emailed to you. That is how these archives usually arrive, and it means the key has been through at least two mail systems and is sitting in at least four mailboxes.
Strictly, the key should never have left the machine that generated it: the request goes out, the certificate comes back, the key stays. Where that ship has sailed, the recoverable position is to treat the delivered key as compromised, generate a new one on the server, and reissue. Certificates are cheap or free; a key that has been through a mail server is not a secret in any meaningful sense.
Where the client will not pay for a reissue, at minimum delete the archive from your mail after installing, and note the date in the client file. It is the kind of thing you want to be able to answer precisely if it ever matters.