3

Manual page for OpenSSL ec command states:

   The PEM private key format uses the header and footer lines:

    -----BEGIN EC PRIVATE KEY-----
    -----END EC PRIVATE KEY-----

   The PEM public key format uses the header and footer lines:

    -----BEGIN PUBLIC KEY-----
    -----END PUBLIC KEY-----
  1. What standard does this base upon (if any)?
  2. Why 'EC' is indicated in the private key header/footer, but not in the public? I assume that this is a piece of "meta-information" describing the content, so why is it missing from the public part?

2 Answers 2

1

For RSA, the RSAPublicKey structure is defined in PKCS#1 standard and SubjectPublicKeyInfo defined for X509 simply uses definitions from PKCS#1. So there are two forms for RSA public keys which PEM format distinguishes :

  • one with 'RSA' - RSAPublicKey
  • one without 'RSA' - SubjectPublicKeyInfo wrapping RSAPublicKey

EC is defined in RFC5915 and does not provide the ECPublicKey structure instead referring to SubjectPublicKeyInfo from X509 as a vehicle for public key sharing. Therefore 'BEGIN EC PUBLIC KEY' would simply be equivalent to 'BEGIN PUBLIC KEY' which uses SubjectPublicKeyInfo structure.

In short : this discrepancy is due to historical reasons and the order in which things were invented and standardized.

3

To answer your first question, this is based on the RFC https://www.rfc-editor.org/rfc/rfc5915 (section 4)

The missing algorithm name has to do with the encoding format used while encoding i.e. pkcs#1 vs pkcs#8. The first one doesn't contain the algorithmIdentifier and hence the algo name(EC, RSA etc.) is included in the label. However, pkcs#8 encapsulates the algorithm identifier and hence it's omitted from the label.

for example, pkcs#8 format for private key is this:

PrivateKeyInfo ::= SEQUENCE {
   version                   Version,
   privateKeyAlgorithm       PrivateKeyAlgorithmIdentifier,
   privateKey                PrivateKey,
   attributes           [0]  IMPLICIT Attributes OPTIONAL }

Version ::= INTEGER

PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier

PrivateKey ::= OCTET STRING

Attributes ::= SET OF Attribute

To clarify, there is nothing preventing one to represent the public key in pkcs#1 format and thus creating a header of the type: -----BEGIN EC PUBLIC KEY-----. So it seems that the particular encoding produced is according to the default encoding set for the tool(I am not sure of this though). Nevertheless, any decent tool/library should be able to gracefully handle either format, even when different formats are used for the public and private keys of the same key-pair.

5
  • And the other "BEGIN PUBLIC KEY"? Aug 30, 2018 at 17:55
  • updated my answer. However, exactly why openssl behaves this particular way, I do not know. Aug 30, 2018 at 18:48
  • But the public key is not written in PKCS#8. openssl asn1dump shows a very simple structure, containing just two "OBJECT"s and one "BIT STRING". It is something else. Aug 31, 2018 at 9:41
  • (starting answering own question) security.stackexchange.com/a/84331/50647 tells about SEC-1 specification, which suggests ASN.1 encoding for EC keys (both private and public). It looks like OpenSSL follows this recommendation and then adds (not really specified anywhere?) PEM headers. Aug 31, 2018 at 9:51
  • 2
    PKCS1 is the algorithm-specific form for RSA only not EC. The EC privatekey syntax was defined by SECG SEC1, as stated in rfc5915; the EC publickey syntax was defined by X9.62 and adopted with some restrictions by PKIX (rfc3279 and rfc5480) and SEC1. And PKCS8 is the generic format only for privatekey; for publickey it is X.509 and mostly the PKIX profile thereof. Aug 31, 2018 at 10:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .