Monday, November 23, 2015

Least fun Bouncy Castle ever. Making Java crypto play with everyone else.








This really sucked, and didn't appear anywhere on the web, so here what I found.

When you use Bouncy Castle to generate ECDSA (and probably the rest) signatures - it does something different that most - rather than just packing the r and s into a byte[] and calling it a day - it packs it into a DER structure, which hold both big integers in ASN.1.  Which is a bunch of acronyms and probably warns that this is going to be really annoying.  The spec appears to be for-pay only - so you need to look at source and guess what it means.  If you hex dump what BC generates:

00000000 30 46 02 21 00 D8 33 C8 A5 26 B5 99 16 D2 A0 2E 0F.!..3..&......
00000010 97 FC 1D 6B 96 EB FA 5A FF 8F 8A 19 8F 3E 56 83 ...k...Z.....>V.
00000020 40 79 8E DC 26 02 21 00 E7 E8 87 F8 4E 97 F3 43 @y..&.!.....N..C
00000030 79 7E D1 D8 E5 A9 BD C1 8C 70 2E BA 6D 9E CC 19 y~.......p..m...
00000040 83 ED 36 CE 65 05 82 BF                         ..6.e...

The packing is pretty easy - the first byte is always 0x30, second is total size, and the third is number of items.  After that it gets goofy - a big int is 32 bytes (0x20) - but the r and s blocks are sometimes 32 and sometimes 33.  It looks like for some reason if the high bit is set in the following element it throws in a random 0x00 to keep things from getting too crazy with all those ones.  If the size is 33 - toss the extra byte and read the next 32.  After which there's an element count to skip and another size for poor s.

Doing this by eye - here's the 'good' data from this hex dump:

00000000 30 46 02 21 00 D8 33 C8 A5 26 B5 99 16 D2 A0 2E 0F.!..3..&......
00000010 97 FC 1D 6B 96 EB FA 5A FF 8F 8A 19 8F 3E 56 83 ...k...Z.....>V.
00000020 40 79 8E DC 26 02 21 00 E7 E8 87 F8 4E 97 F3 43 @y..&.!.....N..C
00000030 79 7E D1 D8 E5 A9 BD C1 8C 70 2E BA 6D 9E CC 19 y~.......p..m...
00000040 83 ED 36 CE 65 05 82 BF                         ..6.e...

No comments:

Post a Comment