14

When I'm generating a private key with openssl, it writes the curve's parameters, and the actual private key:

❯ openssl ecparam  -name secp256k1 -genkey
-----BEGIN EC PARAMETERS-----
BgUrgQQACg==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIKYV1xoz6smkpdMksfgI8/3465V02UZdaKj4JSH30bBhoAcGBSuBBAAK
oUQDQgAEO1O+/xRGEVJgBEAOQorBveXPTQS3c7MA+9R+HEMP7TkscI9FONPclcRb
5sXZJjYHNYWhvxuXdGl8QrFVRIVBYg==
-----END EC PRIVATE KEY-----

Note that the parameters does not contain real data, just reference to the standard used:

❯ openssl ecparam  -name secp256k1 | openssl asn1parse
    0:d=0  hl=2 l=   5 prim: OBJECT            :secp256k1

However when I look at the private key, I can see that it contains the curve type used! Look at the line starting with 41:d

❯ openssl ecparam  -name secp256k1 -genkey -noout | openssl asn1parse
    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      [HEX DUMP]:872F67D0B852C6FE9BD1F5B93AF54B7555D21267200DA2F8ED735729BF32730A
   39:d=1  hl=2 l=   7 cons: cont [ 0 ]        
   41:d=2  hl=2 l=   5 prim: OBJECT            :secp256k1
   48:d=1  hl=2 l=  68 cons: cont [ 1 ]        
   50:d=2  hl=2 l=  66 prim: BIT STRING

Is there a reason I need the EC parameters? Why does it produce them by default?

(The only reason I can think of needing those EC parameters, are to use them as an input when generating a private key, but aren't you better off give their name in the command line?)

Jon-Eric
  • 105
  • 4
Elazar Leibovich
  • 519
  • 2
  • 7
  • 14

1 Answers1

16

It is a quirk of OpenSSL. The ecparam command is meant for handling EC parameters -- namely, the definition of a curve to play on -- and allows the generation of a private key as a secondary feature. You can use the -noout command-line argument to suppress the production of the encoded EC parameters themselves:

$ openssl ecparam -name secp256k1 -genkey -noout
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIHyx/m9I6/ZbvqN5XJ/fZSM6P7PIuvNDnWdp8STjlGqQoAcGBSuBBAAK
oUQDQgAEVGRwTHlFRgxmhnJNO4Vfdojmg2pni44U4SMFEziNM8YVhd62UzwB5L0+
n8EXsvTIv5Uj7COQd/1cTsdL9kin4w==
-----END EC PRIVATE KEY-----

Also, the existence of an "EC parameters" stand-alone structure is justified by the fact that the private key encoding could lack the information; see RFC 5915 which gives the following ASN.1 type:

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

where the parameters and publicKey fields are duly marked as "optional".

As for the internal representation of the parameters (either stand-alone or as part of the private key structure), the use of a simple OID is rather normal. Generating your own elliptic curve is substantially harder than producing new DSA parameters; also, sticking to a few standard curves makes implementation of EC cryptography both easier and faster. Therefore, most implementations out there are restricted to a few standard curves, often the P-256 and P-384 from NIST (actually from SEC, then "annexed" by NIST). Implementations which support all 15 standard NIST curves are a rarity; implementations which support "arbitrary" curves (where the full curve values are encoded in the parameters structure) are mythical (I never stumbled on one, although I got close to writing one at some point).

Thomas Pornin
  • 320,799
  • 57
  • 780
  • 949