# ECDSA private key format

Here's a sample ECDSA private key (I don't use it for anything):

-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIFL3sLnioGcDvHWM/BPlNw96BOx1KKco2qsq4UwhQUosoAcGBSuBBAAK
oUQDQgAEXs1Fmq4QdPAbn3NycdEU+HOjc3kW9efbso2kI/vdDTWcSCMk310s53G3
-----END EC PRIVATE KEY-----


Here's what OpenSSL's asn1parse says about it:

    0:d=0  hl=2 l= 116 cons: SEQUENCE
2:d=1  hl=2 l=   1 prim:  INTEGER           :01
5:d=1  hl=2 l=  32 prim:  OCTET STRING
39:d=1  hl=2 l=   7 cons:  cont [ 0 ]
41:d=2  hl=2 l=   5 prim:   OBJECT            :1.3.132.0.10
48:d=1  hl=2 l=  68 cons:  cont [ 1 ]
50:d=2  hl=2 l=  66 prim:   BIT STRING


My question: where is this format defined?

You can find the definition in RFC 5915.

It defines an ECPrivateKey object:

ECPrivateKey ::= SEQUENCE {
version        INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
privateKey     OCTET STRING,
parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
publicKey  [1] BIT STRING OPTIONAL
}


From Section 3:

The fields of type ECPrivateKey have the following meanings:

• version specifies the syntax version number of the elliptic curve private key structure. For this version of the document, it SHALL be set to ecPrivkeyVer1, which is of type INTEGER and whose value is one (1).
• privateKey is the private key. It is an octet string of length ceiling $$(\log_2(n)/8)$$ (where $$n$$ is the order of the curve) obtained from the unsigned integer via the Integer-to-Octet-String- Primitive (I2OSP) defined in RFC3447.
• parameters specifies the elliptic curve domain parameters associated to the private key. The type ECParameters is discussed in RFC5480. As specified in RFC5480, only the namedCurve CHOICE is permitted. namedCurve is an object identifier that fully identifies the required values for a particular set of elliptic curve domain parameters. Though the ASN.1 indicates that the parameters field is OPTIONAL, implementations that conform to this document MUST always include the parameters field.
• publicKey contains the elliptic curve public key associated with the private key in question. The format of the public key is specified in Section 2.2 of RFC5480. Though the ASN.1 indicates publicKey is OPTIONAL, implementations that conform to this document SHOULD always include the publicKey field. The publicKey field can be omitted when the public key has been distributed via another mechanism, which is beyond the scope of this document. Given the private key and the parameters, the public key can always be recomputed; this field exists as a convenience to the consumer.

As pointed out in the comments, OpenSSL actually uses a slightly different format, namely the SEC1 format found in SECG's SEC 1: Elliptic Curve Cryptography. From the description of the openssl ec command:

-inform DER|PEM

• This specifies the input format. The DER option with a private key uses an ASN.1 DER encoded SEC1 private key.

However, as was also noted, the differences are small even if they are worth noting. From RFC 5915's Appendix B:

This appendix lists the differences between this document and SECG1:

1. This document uses the I2OSP routine defined in RFC3447 while SECG1 defines its own routine. The two routines result in the same output.
1. SECG1 constrains its parameters (i.e., the curves) to SECGCurveNames. This document constrains the parameters to NamedCurve from RFC5480.
1. This document requires parameters be present while SECG1 does not.
1. This document specifies requirements for encoding rules while SECG1 did not.
• Given OpenSSL implemented this long before 2010, I'm pretty sure they actually followed SECG 'SEC1', which is effectively identical -- especially since OpenSSL does implement non-named 'explicit' parameters (Fp and F2m) and at least used to default to them on the API, frequently causing interop trouble. Jun 29 '17 at 6:36
• Wow, thanks. Edited the post to add this discussion.
– user47922
Jun 29 '17 at 14:22
• what format is this: 0 43 25 c4 d7 9 f1 9a 46 f7 4a 7c 9e de c2 b3 22 90 47 d1 15 c f4 f0 b 86 5 cc 0 0 0 0 45 e dc df e9 37 34 2 ad 53 b4 95 66 a1 a b4 3c 44 44 37 c3 93 c8 85 18 c9 b3 58 15 8e 79 6a
– sree
May 23 '19 at 11:02
• What I understood from above that all private keys should start with 01 however example in question starts with 0x30... If we convert base64 to binary. Can someone please explain? thanks Sep 29 '21 at 10:25