Convert certificates, requests, CRLs, keys and PKCS#7 bundles between PEM text and DER binary. The object type and the PEM label are read from the bytes, not asked for.
Initializing in your browser…
Build a PKCS#10 certificate signing request with subject alternative names, RSA, ECDSA or Ed25519. Signed and verified in the page before you send it to a CA.
Decode an X.509 certificate field by field, check which host names it covers, and verify that each certificate in a chain was signed by the one above it
Generate SSL/TLS certificates for local development, with hostnames placed in the Subject Alternative Name where browsers look. Exports PKCS#8, PKCS#1 and PKCS#12, with fingerprints and install config.
A colleague sends you a 121-byte binary file called server.key and your web server will not load it. There is no label on a DER file to tell you what is inside.
The first 24 bytes of the file
3077 0201 0104 2088 112f eaf8 c714 90e0 3b5d 1344 aff4 3e4a
What the tool says, and what it writes
EC PRIVATE KEY 121 DER bytes, read from binary DER A SEC1 ECPrivateKey: the private scalar, the curve and usually the public point. Defined in RFC 5915 section 3. How this was decided: version 1, the private scalar as an OCTET STRING, then the curve and the public point. -----BEGIN EC PRIVATE KEY----- MHcCAQEEIIgRL+r4xxSQ4DtdE0Sv9D5Kc6jv2jxR/+wEV4uhWhp+oAoGCCqGSM49 AwEHoUQDQgAEtEkgueZhIh3rtAYv1i9Wlpu0U8OkOuTICDRgZkUEFOlQJbALiN7C GmC7H+8YkvV+yTEj2sRN1bqoPb3Tw+pR+w== -----END EC PRIVATE KEY----- Checked: the PEM was read back and the bytes came out 121 bytes identical.
The 0x30 0x77 opens a 119-byte SEQUENCE; 0x02 0x01 0x01 is an INTEGER of 1; 0x04 0x20 is a 32-byte OCTET STRING. That combination is a SEC1 ECPrivateKey and nothing else, so the label is EC PRIVATE KEY. It matters because the three private key formats wear three different labels: PRIVATE KEY is PKCS #8, RSA PRIVATE KEY is PKCS #1, and EC PRIVATE KEY is SEC1. Write these bytes under the PKCS #8 label, which is what a converter does when it offers you a "Private Key" button and takes your word for it, and openssl answers "Could not find private key of key" without naming either format, which is why the error is so hard to act on.
The PEM above is byte for byte what openssl pkey itself writes for the same key, including the 64-character line width RFC 7468 section 2 specifies. Every one of the fifteen object types in the project tests is checked this way: the PEM the page produces is written to disk and read back by the openssl sub-command that its own label implies, so a label a reader cannot use counts as a wrong answer even when the bytes are right.
Convert certificates, certification requests, revocation lists, keys and PKCS#7 bundles between PEM text and DER binary. The object type is read out of the ASN.1 structure, so the PEM label is right without you having to know which of PKCS #1, PKCS #8 or SEC1 you were handed.
PEM and DER are two encodings of the same ASN.1 data, and the conversion between them is pure encoding: a DER file is the binary itself, and a PEM file is that same binary in base64, wrapped in a BEGIN and END line naming a label, at 64 characters a line as RFC 7468 section 2 requires. No cryptography happens here and nothing is uploaded.
The label is the part that matters, and it is the part tools get wrong. It is not decoration: every reader picks its parser from it. A PKCS #1 RSA key written under the PKCS #8 "PRIVATE KEY" label is refused outright by openssl pkey, which reports "Could not find private key of key"; a SEC1 elliptic curve key under the same label is refused the same way; and a revocation list written under "CERTIFICATE" is refused by everything. So this tool does not ask you what the file is. It reads the ASN.1 structure and works it out: a PKCS #8 key opens with an INTEGER version of 0 followed by an algorithm identifier and an OCTET STRING, a SEC1 key opens with an INTEGER of 1 followed by an OCTET STRING, a certificate keeps its two validity times inside a SEQUENCE while a revocation list carries thisUpdate as a bare Time directly, a certification request is version, subject, public key and a [0] attribute set, and a CMS ContentInfo opens with a content type OID. The reading it made, and the structural fact that decided it, are both shown on screen so you can disagree.
Fifteen labels are recognised and written: CERTIFICATE, CERTIFICATE REQUEST, X509 CRL, PUBLIC KEY, RSA PUBLIC KEY, PRIVATE KEY, RSA PRIVATE KEY, EC PRIVATE KEY, ENCRYPTED PRIVATE KEY, PKCS7, CMS, DH PARAMETERS, EC PARAMETERS, DSA PARAMETERS and ATTRIBUTE CERTIFICATE, each shown with the document that defines it. Two more, OPENSSH PRIVATE KEY and SSH2 PUBLIC KEY, are recognised and refused, because they are not ASN.1 at all and have no DER form. One case is genuinely undecidable and is reported as such rather than guessed: a SEQUENCE of two INTEGERs is both a PKCS #1 RSAPublicKey and a DH parameter set, and nothing in the encoding separates them, so both readings are offered with the reason. You can override the label at any point, and if you pick one the bytes are not, the page says so before you copy it.
Input arrives as a pasted PEM block, as bare base64 of DER, as hex of DER, or as a file. Whether a file is text or binary is decided by reading it, not by its extension, because a .cer is PEM about as often as it is DER and a .key holding DER is common. Text before and after the block is ignored, so the output of openssl x509 -text pastes in and works; CRLF line endings, bodies wrapped at widths other than 64, and files holding several objects are all handled, and a chain file gives you every certificate in it separately rather than gluing them together. A legacy encrypted PEM carrying RFC 1421 Proc-Type headers is recognised and refused with the reason, since its encryption sits outside the DER. After conversion the tool reads its own PEM back and reports whether the bytes came out identical, and it prints the openssl command that reads the result under the label it wrote.
A key exported as PKCS #1 or SEC1 but saved under the PKCS #8 label is the usual cause of "unable to load private key". Paste it and the tool names which of the three it actually is.
keytool and the Windows certificate store want DER (.cer, .der) where nginx, Apache and OpenSSL want PEM. Convert either way and download the real bytes.
A fullchain.pem holds the leaf and every intermediate. The tool lists them separately so you can take just the one you need.
A bare .der or .bin with no label at all is identified from its structure, including revocation lists and PKCS#7 bundles that most converters cannot name.
DER is the binary encoding. PEM is that same binary in base64, wrapped in BEGIN and END lines naming a label, at 64 characters a line. The conversion is lossless in both directions and involves no cryptography.
Almost always the PEM label. PRIVATE KEY means PKCS #8, RSA PRIVATE KEY means PKCS #1, and EC PRIVATE KEY means SEC1, and they are three different structures. Writing PKCS #1 bytes under the PKCS #8 label produces a file openssl pkey refuses. This tool reads the structure and writes the matching label.
If a text editor shows -----BEGIN something-----, it is PEM. If it is unreadable binary, it is DER. You do not have to work it out here: drop the file in and the tool tells you what the bytes are and why.
No, and neither can anything else. Both are a SEQUENCE of two INTEGERs and the encoding does not separate them. The tool offers the more likely reading based on the size of the second integer, names the other one, and says plainly that only the PEM label settles it.
Yes. Every object is listed separately with its own label and byte count, so a fullchain.pem gives you the leaf and each intermediate individually. Concatenating them into a single DER, which is what a naive converter does, produces bytes that most readers silently truncate.
No, and it says so rather than producing something broken. An OpenSSH private key is not ASN.1: it is an OpenSSH-specific container of length-prefixed fields, so it has no DER form. Convert it with ssh-keygen instead.
A PKCS #8 encrypted key (ENCRYPTED PRIVATE KEY) converts between PEM and DER like anything else, since the encryption is inside the DER. A legacy PEM key with Proc-Type and DEK-Info headers cannot, because there the encryption sits outside the DER; the tool recognises those headers and explains why.
This runs as client-side JavaScript. Keys, tokens, payloads, and other inputs never leave your device.