1

EVP_DigestSignFinal() gives me a DER encoded signature.

Some examples:

ECDSA-SHA-256

30 44 02 20 [..r..] 02 20 [..s..]
30 46 02 21 [..r..] 02 21 [..s..]
30 45 02 20 [..r..] 02 21 [..s..]

ECDSA-SHA-224

30 3d 02 1c [..r..] 02 1d [..s..]
30 3c 02 1c [..r..] 02 1c [..s..]

The size can vary and I want to concatenate them. What's a good way to know how many bytes the signature will be long? Or is there a function in OpenSSL that's already implemented maybe?

1 Answer 1

2

The ECDSA signature is encoded as an ASN.1 structure, which is a SEQUENCE of two INTEGER values. When encoded, the first byte will by 0x30 (which means SEQUENCE), followed by the length, encoded over one or two bytes: if length is n bytes, then it will be encoded as a single byte of value n if n ≤ 127, or two bytes of value 0x81 then n, if 128 ≤ n ≤ 255 (the latter case may happen in case you use a "large" curve like P-521). These n bytes are the concatenation of the two INTEGER values, each with its own tag (a byte of value 0x02), then its length (same encoding; in practice, over a single byte, since it would take a 1000-bit or so curve to need more than one), then the INTEGER value. The value of an INTEGER uses signed big-endian (so you may have a leading byte of value 0x00).

Properly encoding and decoding ASN.1 structures is a difficult art. I don't know if OpenSSL has a public function for that. This function, from another SSL library, converts from ASN.1 to "raw" ECDSA signatures ("raw" means: the two integer values are simply encoded in big-endian and concatenated, both being adjusted to have the same encoding length).

Not the answer you're looking for? Browse other questions tagged .