Given an arbitrary (valid!) private or public key encoded inside of a PEM, with the pre-encapsulation boundary
and post-encapsulation boundaries
intact, is it possible to know exactly what format the bytes take (i.e. are they OpenSSL traditional, PKCS8, X.509 SubjectPublicKeyInfo
, etc.), or does one need some a priori information to properly decode them?

- 14,353
- 9
- 63
- 113
-
`BEGIN SOMETHING` boundary is a hint that content is probably SOMETHING, but it is not binding, meaning that PEM reader should not assume the specific content based on boundary title and should just use the boundary to, well, find out the document bounds. – Oleg Estekhin Jul 14 '14 at 18:17
2 Answers
With certificates the situation is almost straightforward - there the boundary line specifies what is expected (a certificate or a private key).
In OpenPGP armored data the boundary line also tells you what is expected - the key(s) or the data.
SSH keys created by several SSH applications have the same boundary lines but different format of the key itself. So you need to try reading the data in all expected formats.
RSA public keys usually have RSA 1.5 format so you can assume that you have an RSA key.
PKCS#12 is not usually wrapped to PEM (I never saw such files). The same goes for PKCS8.
PKCS#7 certificate storages are sometimes PEM-encoded and they have something like BEGIN CERTIFICATE STORAGE in their boundary line.
To sum it up - to some extent you can rely on the boundary line text, but this doens't give you a 100% guarantee.

- 45,135
- 8
- 71
- 121
You should have a look at the specification, PKCS#8 is specified in RFC5958 in Section 5
When .p8 files are PEM encoded they use the .pem file extension. PEM encoding is either the Base64 encoding of the DER-encoded EncryptedPrivateKeyInfo sandwiched between:
-----BEGIN ENCRYPTED PRIVATE KEY-----
-----END ENCRYPTED PRIVATE KEY-----or the Base64 encoding, see Section 4 of [RFC4648], of the DER-encoded PrivateKeyInfo sandwiched between:
-----BEGIN PRIVATE KEY-----
-----END PRIVATE KEY----
Slightly longer answer: "Between the tags is in any case valid Base64 Encoded DER encoded ASN.1"