I am using a secure embedded chip (ATECC508) to generate an ECDSA message/signature combination using the secp256r1 curve.
The information from the chip outputs in Uint8Arrays: message[32], signature[64], and publickey[64]; The public key is in raw byte format, giving both X/Y coordinates in a 64 byte array, without the 0x04 padding on the front.
The public key will only successfully import into WebCrypto as long as I pad the 64 byte array with 0x04 on the front.
However, when I attempt to verify the message and signature, it always fails.
I created a simulator script to help debug. It uses WebCrypto to generate the message, signature, and public key instead of the crypto chip. The simulator generates a 32 byte Uint8array message array, and signs the message returning a 64byte Uint8array for its signature. The public key that WebCrypto generates is also verified to have the 0x04 padding in the front, before the 64bytes representing the X/Y coordinates of the curve. This means I believe that the information generated by the simulator should be in the exact same format as what the chip provides.
Any message, signature and public key which is generated from WebCrypto can be successfully verified...but I cant authenticate the information from the chip...it is always unsuccessful.
I have no reason to suspect the values from the chip are wrong, and I have generated many messages/signatures from the chip...none of them work. I have also tried a second chip with the same result.
Output example from chip (does not verify):
uint8_t message[32] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
};
uint8_t signature[64] = {
0xD6,0x82,0x25,0xCC,0x68,0x6F,0x4F,0x84,0x91,0x48,0x63,0x6E,0x67,0x3C,0xD4,0xC0,0xF8,0xE5,0x9D,0x7B,0xAD,0x6B,0xB3,0xF1,0x1C,0xDB,0x90,0xB7,0x1A,0x5E,0x43,0xCF,0xD8,0xC3,0x8C,0x77,0x74,0xE2,0xA0,0x29,0xFF,0x43,0x22,0x7D,0xF9,0x41,0x56,0x12,0x8A,0x1B,0xEA,0x4D,0x57,0x8A,0x37,0x9C,0x6A,0x85,0x0A,0x56,0xBE,0xEC,0x1A,0x69
};
uint8_t publicKey[64] = {
0x39,0xC3,0xDD,0x74,0x13,0x17,0x29,0x44,0x6D,0xC1,0xB3,0xDA,0x67,0xD4,0x9F,0xC0,
0x46,0xFC,0xBF,0x07,0x2F,0xCC,0x5B,0x9F,0xA5,0x1C,0x05,0xB9,0x74,0x30,0x7F,0x96,
0x9C,0x40,0x3B,0x16,0x35,0xF0,0x44,0x9F,0x02,0xBD,0x42,0x27,0x51,0xE3,0x31,0x21,
0xA4,0x43,0x4F,0x15,0x2F,0x2B,0x2B,0x2A,0x3F,0x67,0x52,0x19,0xC5,0xD9,0x25,0xF6,
};
Note: The public key above is padded with 0x04 before importing, otherwise WebCrypto throws an error.
Output example from WebCrypto simulator javascript console (this verifies OK):
Message to import in hex: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
Message Uint8Array conversion: Uint8Array(32) [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, … ]
the signature in hex: 5d4575a19cad9a56b554bafbb1db212d8badd48b5d29f6556fa33f0e8650175f48157e70377c7aa5f97e55bc455b6520060dc86f32a00577a254a97e1b7b394c
the signature buffer:
Uint8Array(64) [ 93, 69, 117, 161, 156, 173, 154, 86, 181, 84, … ]
public key in hex:
04d18669eb64b54118fbcdacbf79d2f185383abadb1982382a51675650f4596d9f917a7b9b215f2424418b4e7c824500dc29ea507f08b4ef51ca35f58de75ca274
note: above are hex strings, but I am converting to a UintArray8 before calling WebCrypto API using. PublicKey is converted into the correct CryptoKey() type before using to verify.
The javascript code I am using for verification:
let result = await window.crypto.subtle.verify({
name: "ECDSA",
hash: { name: "SHA-256" }
},
publicKey, sigbuffer, msgbuffer);
And finally, the import:
return window.crypto.subtle.importKey(
'raw',
key, {
name: 'ECDSA',
namedCurve: 'P-256'
},
true, ["verify"]
);
My intention is to be able to import and verify the information from the chip successfully into the WebCrypto API, but I have so far been unsuccessful. At the moment I am completely stuck and would be extremely grateful for any help...thanks in advance