How is EC key encoded in PKCS#8? I just started working with certificates and signatures. For an application I write I need a key pair for ECDSA signatures, using the elliptic curve secp384r1 (aka NIST P-384).

I produced such a key pair with the Bouncy Castle lib in Java. Just for testing purposes I then used the JcaPEMWriter to write the two keys to files.

I got the following results:


  -----BEGIN EC PRIVATE KEY-----
  MDUCAQEEMB4Tr3coGQbhIax2Aqs3IJW3D2QmsG1efvhrCeY+6F0K9fTAFT1+mTyL
  ENJ2lUdD/Q==
  -----END EC PRIVATE KEY-----


and


  -----BEGIN PUBLIC KEY-----
  MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEhUvTJddWZidioBHCnPk23SH2C1lITFEK
  UGH63OqRcbE3cfGkykx0XUdHh8ZIKMUhikKr8+ln59sh7Tz1D6TqjtNPsuEMO07t
  ykzbQM+xZT0DMwnVNx+B0UT1Rr9JrNVX
  -----END PUBLIC KEY-----


My questions are:

1) Why is the format of the two key representations different? The private key is in PKCS#8, the public key in X.509 format (at least that is what Java's "getFormat" method tells me). I think there must be some good reason why the developers decided for these different representations, but for me it is just confusing ;-). Is this due to some standard?

2) Next I went to https://lapo.it/asn1js to decode the keys. For the public key I got some information about the algorithm used, and then a 776 bit string. These are 97 bytes. If I understand it correctly, those are made up of one byte telling me that the elliptic curve point is in uncompressed encoding, 48 bytes (=384 bit) for the x-coordinate and 48 bytes for the y-coordinate.

But when I try to decode the private key in the same manner, I get only 48 bytes for the actual key. What exactly do these bytes represent? Is this the curve point in it's compressed form? But in this case, shouldn't there be a flag at the beginning telling me that this is compressed form?

Maybe you can help me get a better understanding of what's going on here. Thank you in advance!
But when I try to decode the private key in the same manner, I get only 48 bytes for the actual key. What exactly do these bytes represent? Is this the curve point in it's compressed form? But in this case, shouldn't there be a flag at the beginning telling me that this is compressed form?


When we generate an EC public/private key pair, we pick a number $x$ and compute the elliptic curve point $xG$, which is $G$ (the well-known "generator point") added to itself $x$ times.

The public key is the point $xG$; because it is a point, we need to state whether we're expressing that point in compressed or uncompressed format.

In contrast, the private key is just the value $x$; this is just an integer, and so doesn't need to be 'compressed'.

As for why your $x$ is 48 bytes (or about 384 bits), we try to select the integer randomly between 1 and the size of the group (which is, in your case, circa $2^{384}$); selecting from a smaller range would reduce the security we get, and selecting from a larger range wouldn't help.