Background I am trying to understand how PEM contents are formatted for "EC Private Key" so e.g. following is private key


which was created with following openssl command just in case anyone like to see

openssl ecparam -out ecc_private_key.key -name secp521r1 -genkey

Recently I realized that contents in between -----XXX EC PRIVATE KEY----- contains more than just private key and cannot be used a Parameter "D" in elliptic curve equation. So using following command I was able to find individual elements also given below;

$ openssl ec -in ecc_private_key.key -noout -text
read EC key
Private-Key: (521 bit)
ASN1 OID: secp521r1

Question: I would like know that how openssl able to decode Base64 contents and extracted private and public key out of it. I am currently dealing with an app which does not have any PemReader abilities built in so I would like to write my own implementation of PemReader so I can decode this information in my application (only EC keys for now)

PS: I already have gone through RFC5915 according to that Private-Key should start with 1 (version) but all key I generate with openssl always start with 0x30. So I am missing something of course

  • $\begingroup$ 5915 #3 says it's ASN.1 type ECPrivateKey which is a SEQUENCE containing INTEGER with value 1 etc. The DER (or BER) encoding of a SEQUENCE begins with the tag for SEQUENCE which is 0x30. $\endgroup$ Sep 30 at 23:35

The private key data is encoded in ASN.1, so you need to decode that to get the various fields out. openssl asn1parse can do this, but by default it'll parse the "EC PARAMETERS" section of the file (since that comes before the "EC PRIVATE KEY" section), so you need to strip that off first. You can do that with sed, and then pipe the result to openssl asn1parse:

$ sed '1,/-----BEGIN EC PRIVATE KEY-----/ d' ecc_private_key.key | openssl asn1parse --dump
    0:d=0  hl=3 l= 220 cons: SEQUENCE          
    3:d=1  hl=2 l=   1 prim: INTEGER           :01
    6:d=1  hl=2 l=  66 prim: OCTET STRING      
      0000 - 00 6a fa 62 51 c9 35 95-07 34 d4 0e 85 1f 54 84   .j.bQ.5..4....T.
      0010 - d5 74 b0 5b 80 be 8b 7e-78 b4 e4 32 3e 38 a8 4a   .t.[...~x..2>8.J
      0020 - 7a b9 97 37 3d 61 05 d7-c8 02 22 0b a8 62 32 10   z..7=a...."..b2.
      0030 - 11 cc 1c 5e da f9 98 05-e0 84 10 d9 66 08 6d 23   ...^........f.m#
      0040 - 37 29                                             7)
   74:d=1  hl=2 l=   7 cons: cont [ 0 ]        
   76:d=2  hl=2 l=   5 prim: OBJECT            :secp521r1
   83:d=1  hl=3 l= 137 cons: cont [ 1 ]        
   86:d=2  hl=3 l= 134 prim: BIT STRING        
      0000 - 00 04 01 32 31 0f f6 36-45 34 2c 74 c1 86 9b 1b   ...21..6E4,t....
      0010 - 79 a1 64 94 d4 97 51 e1-b6 ce 72 ee 16 f7 1b d2   y.d...Q...r.....
      0020 - 1b dc db d4 79 c9 dc fc-fd da 43 3a 18 44 b5 3d   ....y.....C:.D.=
      0030 - fe 49 18 98 3a 60 52 7f-9c 10 45 15 b2 7f ce f6   .I..:`R...E.....
      0040 - 5c 5b 71 86 01 a9 e8 c1-6b 7c 72 f4 73 6a 1f bd   \[q.....k|r.sj..
      0050 - 82 1f c4 b2 4f 5d 29 ea-f8 60 aa 38 a8 bc dc 6c   ....O])..`.8...l
      0060 - 0a 21 37 e4 91 df 4d 8b-07 d6 ed 89 4a 6c 04 0f   .!7...M.....Jl..
      0070 - 4a 83 dc 0a 83 c6 f9 c3-42 30 bb 37 14 b3 7f e9   J.......B0.7....
      0080 - f0 fa 2b df 51 ff                                 ..+.Q.

BTW, you've now published this private key to the Internet... so please don't ever use it for anything you want to actually be secure.

  • $\begingroup$ thanks for answer I am going through that. Of course this is just a sample key and not intended to be used in production. $\endgroup$
    – Mubashar
    Sep 30 at 2:13

Before looking into PEM/ASN.1: EC private key is a prime field element, almost a bignumber. EC public key is a point on the curve, (most likely) encoded as two field elements, either prime-field (that is, modulo another prime) or binary extension field. So you look into curve description for background. Just pick two prime numbers for secp521r1 (from your trusted source) to understand both fields. Also pick "a" and "b" coefficients and group generator.

To summarize: decode your private key down to a bignumber modulo group order, and two bignumbers ("x" and "y" coordinates of the point on elliptic curve) modulo base-field-prime as the public key.

Follow Gordon Davisson' answer for details, remember BITSTRING at the public key is another SEQUENCE to decode.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.