It happens that there are many standards for storing cryptography materials (key, certificate, ...) and it isn't always obvious to know which standard is used by just looking at file name extension or file content. There are bunch of questions on stackoverflow asking about how to convert from PEM to PKCS#8 or PKCS#12, while many tried to answer the questions, those answers may not help because the correct answer depends on the content inside the PEM file. That is, a PEM file can contain many different things, such as an X509 certificate, a PKCS#1 or PKCS#8 private key. The worst-case scenario is that someone just store a non-PEM content in "something.pem" file.
When working with cryptography material, I usually follow the 3 steps below:
- Inspect what format the material is in
- Understand what format it is required for (for example: logstash server need a PKCS#8 keystore for TLS communication)
- Convert the material
This gist contains my own understanding about different cryptography standards and their uses, so it's surely imperfect. Feel free to contact me for any improvement.
|Standards||Content format||File encoding||Possible content|
|PKCS#1||X||RSA keys (public/private)|
|PKCS#8||X||Private keys, encrypted private keys|
|PKCS#12||X||Certificates, CRLs, private keys|
|JKS||X||Certificates, private keys|
Some formatted contents are not written into file directly as a binary stream. They are first encoded using encoding rules before writing to file. Below is the list of common combinations of content format and encoding rules:
|Content \ Encoding||PEM (*)||DER (**)||Binary|
(*) You can concatenate multiple PEM files into a big PEM that contains multiple materials, such as a complete certificate chain.
(**) You can’t simply concatenate DER file to create single DER file → final file may not be readable by other software. If you need to store multiple materials, check (*) or (***).
(***) These formats are designed to store multiple materials.
|PKCS#1 → PKCS#8||
|PKCS#8 → PKCS#1||
|X509 → PKCS#7||
|PKCS#7 → X509||
|X509 PEM → DER (*)||
|PKCS#1/8 → PKCS#12||
|PKCS#1/8 + X509 → PKCS#12||
|PKCS#12 → PKCS#8 (**)||
|PKCS#12 → JKS||
|JKS → PKCS#12||
|JKS → X509 PEM||
|X509 PEM → JKS||
(*) Similar commands can be used to convert other file (PKCS#1, PKCS#7, PKCS#8) from PEM encoding to DER encoding and vice versa → just need to use the right engine, e.g. x509 for X509, rsa for PKCS#1, …
(**) Only for extracting private key, the output keys are not encrypted. Remove ‘-nodes’ to encrypt output keys.
Tips for recognising
|Content||What to look for|
|PEM-encoded content||• Text file starts with “-----BEGIN …” and ends with “… END …-----”.
• File extensions (hopefully): *.pem, *.crt, *.key
• File extensions: *.p7, *.p7a, *.p7b, *.p7c
|PKCS#12||File extensions: *.p12, *.pfx|
|JKS||File extension: *.jks|
|DER||File extensions: *.der, *.cer|
Note: Use the right file extension when saving your content into file, but don't rely on file extension when reading, use verification/inspection commands whenever possile.