Error: Failed to authenticate request ... due to: Invalid signature: Invalid public key: Malformed Placeholder public key: , error: Error in DER encoding: Invalid length of bit string: -74"

I had to figure out how to encode ECDSA keys a couple years ago for work and what I found is that it’s relatively easy if your key size stays the same. (when compared to something like encoding RSA keys).

I modified IC-Py to write the encoded public to a file so I could deconstruct it. Here is what I got:

30 Sequence
56 Sequence Length (86b)
30 Sequence
10 Sequence Length (16b)
06 Object Identifier
07 OID Length (7b)
2a 86 48 ce 3d 02 01 (id-ecPublicKey)
06 Object Identifier
05 OID Length (5b)
2b 81 04 00 0a (Dfinity-registered OID?)
03 Bit String
42 Bit String Length (66b)
00 Padding

Remaining bytes are the raw key value

04: Compression (0x04 indicates an uncompressed key (both x & y coordinates))

dd 51 8d 76 6b 79 cb e1 7f 96 a4 b1
6e 79 74 19 c2 82 2f 96 f9 1c fe 95
39 73 f4 8c 77 f5 08 72 19 f6 61 05
fe 24 7d a5 95 01 f6 b6 4b 00 74 4d
a0 5e 95 1f 8a be 0f 2e 38 a4 11 97
05 52 bd 5e

So the prestring for all ECDSA 256 public keys included in requests to the IC’s HTTPS interface would be:

let pre_string : Blob = "\30\56\30\10\06\07\2a\86\48\ce\3d\02\01\06\05\2b\81\04\00\0a\03\42\00";

then you would append you raw key value to that and it would be encoded.

Edit:

Just saw an earlier comment saying the tECDSA interface provides a compressed key. Here is post i just found on converting from a compressed key to an uncompressed one.

3 Likes