Convert a .crt or .cer file to PEM
A `.crt`, `.cer` or `.cert` file is usually already PEM-encoded, in which case converting it to `.pem` is just a rename — the extensions carry no information about the encoding. Check the first line: if it reads `-----BEGIN CERTIFICATE-----` the file is PEM already and `cp certificate.crt certificate.pem` is the whole job. If the file is binary, it is DER, and the conversion is `openssl x509 -inform der -in certificate.crt -out certificate.pem`.
First, find out what you have #
The extension tells you nothing about the encoding, so read the file:
head -n1 certificate.crt Expected output
-----BEGIN CERTIFICATE-----
| What you see | Encoding | What to do |
|---|---|---|
-----BEGIN CERTIFICATE----- |
PEM | Nothing. Rename if you like. |
-----BEGIN PKCS7----- |
PEM, but a P7B bundle | Convert P7B to PEM |
-----BEGIN TRUSTED CERTIFICATE----- |
PEM, with OpenSSL trust settings | Re-emit with openssl x509 to strip them |
| Binary noise, or nothing printable | DER | Convert, see below |
file gives the same answer more directly:
file certificate.crt Expected output
certificate.crt: PEM certificate
If it is already PEM #
There is nothing to convert. These files are byte-identical:
cp certificate.crt certificate.pem If you want a genuinely normalised file — one guaranteed to contain a single certificate with no stray text, bag attributes or trust settings around it — pass it through OpenSSL instead of copying:
openssl x509 -in certificate.crt -out certificate.pem If it is DER #
The file below is named binary.crt to keep the two cases distinct — in practice it
would be the same .crt you started with.
openssl x509 -inform der -in binary.crt -out certificate.pem Omitting -inform der here produces PEM routines::no start line, which is
the most commonly misread OpenSSL error there is.
Handling a directory of unknown files #
When a CA hands you a zip of certificates with mixed encodings, convert defensively — try PEM first, fall back to DER:
for f in *.crt *.cer; do
[ -e "$f" ] || continue
out="${f%.*}.pem"
openssl x509 -in "$f" -out "$out" 2>/dev/null \
|| openssl x509 -inform der -in "$f" -out "$out"
done Verify the result #
openssl x509 -in certificate.pem -noout -subject -issuer -dates Expected output
subject=CN = example.com issuer=C = US, O = Example CA, CN = Example Intermediate CA notBefore=Aug 16 00:00:00 2026 GMT notAfter=Nov 14 23:59:59 2026 GMT
Frequently asked questions
- Is .crt the same as .pem?
- Usually, but not by definition.
.pemnames an encoding;.crtnames a role — "this file is a certificate". A.crtis most often PEM-encoded, but it can equally be DER. Check the contents rather than trusting the extension. - What about .cer files from Windows?
- Windows exports both DER and Base64 as
.cer, and the export dialog is where the choice is made. That is why.ceris the least informative extension of the set. Check the first byte. - Can I just rename the file?
- If it is already PEM, yes — renaming changes nothing about the bytes and every tool that reads PEM will accept it. If it is DER, renaming it to
.pemproduces a file that looks right and fails everywhere. - Does the extension matter to nginx or Apache?
- No. Both read whatever path you configure and detect the encoding from the content. The extension is for humans.
References
- openssl-x509(1) — -inform and -outform
- RFC 7468: textual encodings of PKIX structures — defines the PEM armour and what may sit between the BEGIN and END lines