Can I shorten the large ECDSA public key output file from OpenSSL? I am working in a very bandwidth restricted environment where I from time to time have the need to distribute public keys. The distribution happens in bit format, so there is no need for encoding, at best I would like all my data "raw".

It is my understanding that the public key, in compressed form, takes up the space of the curve size+1, e.g. 160 bit curve gives 161 bit public key. However, the output from OpenSSL gives me a much larger key size, e.g. 904 bits for the secp160r1 curve. I reckon there must be a lot of metadata involved.

Edit: I removed the "--- Public key starts here ---" etc and that almost cut the file in half ahem. But still there are 60 bytes/480 bits, a lot more than what I would think of as necessary.

Can I somehow reduce this size, getting rid of metadata? For example extract the key components of the signature and reassemble it in a compatible format on the receiver side? I assume DER encoding also adds overhead, but hardly this much?

Here arethe commands I use, in Cygwin:

$ openssl ecparam -out private.pem -name secp160k1 -genkey
$ openssl ec -in private.pem -pubout -conv_form compressed -out public.pem
Asn1parse to the rescue.

Most of the overhead is from the base64 encoding and the PEM header and footer.

The raw size of the compressed form ASN1 encoding is just 44 bytes for my dummy key.

And 22 of those bytes are for the 161 bits of the actual public key.

$ openssl asn1parse -in compressed_public.pem -i -dump
    0:d=0  hl=2 l=  42 cons: SEQUENCE
    2:d=1  hl=2 l=  16 cons:  SEQUENCE
    4:d=2  hl=2 l=   7 prim:   OBJECT            :id-ecPublicKey
   13:d=2  hl=2 l=   5 prim:   OBJECT            :secp160k1
   20:d=1  hl=2 l=  22 prim:  BIT STRING
      0000 - 00 03 ca f2 7b b8 4c 3c-99 b2 7a 6f fb f3 cf 8f   ....{.L&lt;..zo....
      0010 - 95 b8 77 61 76 dc                                 ..wav.


And if you turn the PEM encoding into raw DER encoding like so...

$ openssl ec -pubin -in compressed_public.pem -outform der -out compressed_public.der
read EC key
writing EC key


...then 44 bytes is the size of your file.

$ stat compressed_public.pem | grep Size
  Size: 113             Blocks: 1          IO Block: 65536  regular file

$ stat compressed_public.der | grep Size
  Size: 44              Blocks: 1          IO Block: 65536  regular file


And just for another look at this: using "dumpas1n", you can see exactly where those 22 non-pubkey bytes went:
(Note: dumpasn1 skips the "00" byte at the beginning of the 22 byte "BIT STRING" object and does not display it. And openssl asn1parse does not.)

$ dumpasn1  | head -n2
DumpASN1 - ASN.1 object dump/syntax check program.
Copyright Peter Gutmann 1997, 1998.  Last updated 27 July 1998.

$ dumpasn1 compressed_public.der
   0 30   42: SEQUENCE {
   2 30   16:   SEQUENCE {
   4 06    7:     OBJECT IDENTIFIER ecPublicKey (1 2 840 10045 2 1)
  13 06    5:     OBJECT IDENTIFIER '1 3 132 0 9'
            :     }
  20 03   22:   BIT STRING 0 unused bits
            :     03 CA F2 7B B8 4C 3C 99 B2 7A 6F FB F3 CF 8F 95
            :     B8 77 61 76 DC
            :   }

0 warnings, 0 errors.


So to answer your question:


  Can I somehow reduce this size, getting rid of metadata?


Yes. You could cut the size down to just the 22 bytes (or 21 bytes if you exclude any leading 00 bytes).

(If you want yet another tool to look at ASN1: Here's that key in asn1js online.)