Does OpenSSL -sign for ECDSA apply ASN1 encoding to the hash before signing?

十年热恋 提交于 2019-12-02 12:07:13

OpenSSL applies ASN.1 DER encoding to the output of the signature.

https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm#Signature_generation_algorithm

  1. Calculate e = HASH (m), where HASH is a cryptographic hash function, such as SHA-2.
  2. Let z be the Ln leftmost bits of e , where Ln is the bit length of the group order n.
  3. Select a cryptographically secure random integer k from [1, n - 1].
  4. Calculate the curve point (x1, y1) = k x G.
  5. Calculate r = x1 mod n. If r = 0, go back to step 3.
  6. Calculate s = (k − 1) x (z + r * dA) mod n. If s = 0, go back to step 3.
  7. The signature is the pair (r, s).

The problem is that the ECDSA algorithm ends with math, not with bytes. Two different conventions have arisen for how to turn that pair of numbers into bytes. (Contrast with RSA, whose last step says how to turn the mathematical value back into bytes and declares that byte sequence to be the signature).

Let's assert that we produced a signature (against secp256r1) with r = 67432751043532511959904657272700966685609390316545000351652696368910338707793 and s = 15800012655857962601029927988066555130680701005265153794330961.

ASN.1 DER

Used by X.509/PKIX and OpenSSL. First declared (that I can find, anyways) by RFC 3279, sec 2.2.3:

When signing, the ECDSA algorithm generates two values. These values are commonly referred to as r and s. To easily transfer these two values as one signature, they MUST be ASN.1 encoded using the following ASN.1 structure:

Ecdsa-Sig-Value  ::=  SEQUENCE  {
     r     INTEGER,
     s     INTEGER  }

DER works best if we build it inside out, so let's encode r.

r is an integer, 67432751043532511959904657272700966685609390316545000351652696368910338707793 in decimal, or 951595A548D156D51655159654ADA548D156D5165195159654ADA54D156D5151 hex. ITU-T-REC-X.690-201508 says that the integer gets encoded as a signed big endian value. Since the most significant byte (0x95) has the high bit set this is a negative number, so we need to insert an extra 0x00 to keep the number positive. So r takes 32+1 = 33 bytes:

02 21 (INTEGER, 33 bytes)
   00 (padding byte)
   95 15 95 A5 48 D1 56 D5 16 55 15 96 54 AD A5 48
   D1 56 D5 16 51 95 15 96 54 AD A5 4D 15 6D 51 51

s has decimal value 15800012655857962601029927988066555130680701005265153794330961, or hexadecimal value 9D51655159654ADA548D156D5165195159654ADA54D156D5151. While it starts with hex 9 it's actually 0x09, so no padding byte is required. s only takes 27 bytes of content, because it's so small compared to r.

02 1A (INTEGER, 26 bytes)
   09 D5 16 55 15 96 54 AD A5 48 D1 56 D5 16 51 95
   15 96 54 AD A5 4D 15 6D 51 51

And now we can calculate the size of the containing SEQUENCE to be 63 bytes:

30 3F (CONSTRUCTED SEQUENCE, 64 bytes)
   02 21 (INTEGER, 33 bytes)
      00 (padding byte)
      95 15 95 A5 48 D1 56 D5 16 55 15 96 54 AD A5 48
      D1 56 D5 16 51 95 15 96 54 AD A5 4D 15 6D 51 51
   02 1A (INTEGER, 26 bytes)
      09 D5 16 55 15 96 54 AD A5 48 D1 56 D5 16 51 95
      15 96 54 AD A5 4D 15 6D 51 51

Or, linearized:

30 3F 02 21 00 95 15 95 A5 48 D1 56 D5 16 55 15 
96 54 AD A5 48 D1 56 D5 16 51 95 15 96 54 AD A5 
4D 15 6D 51 51 02 1A 09 51 D5 16 55 15 96 54 AD 
A5 48 D1 56 D5 16 51 95 15 96 54 AD A5 4D 15 6D 
51 51 

IEEE P1363

Used by Windows.

In this format r and s are taken to be big integers of the same byte size as n, then concatenated. Since r uses all 32 bytes it's good to go. s only uses 26 bytes, so it needs 6 leading 0x00 bytes.

// r
95 15 95 A5 48 D1 56 D5 16 55 15 96 54 AD A5 48
D1 56 D5 16 51 95 15 96 54 AD A5 4D 15 6D 51 51
// s
00 00 00 00 00 00 09 D5 16 55 15 96 54 AD A5 48
D1 56 D5 16 51 95 15 96 54 AD A5 4D 15 6D 51 51

Conclusion

So, OpenSSL applies an ASN.1 encoding to the signature, not the hash. The ASN.1 encoding is "more common" (in that it's what's used in ECC certificates). The Windows/IEEE way is easier. The ASN.1 way usually ends up about 6 bytes larger (or 7 bytes larger on average for secp521r1); but could (1 in 2^32 chance) end up the same size, or (1 in 2^40 chance) smaller.

Also, if you ever find yourself on a committee designing a new signature scheme, remember to add the step declaring the wire representation.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!