Hi,
I am getting signatures from a Nitrokey in DER format. I then process those signatures in Python.
I am using python-ecdsa and occasionally it will raise an error because it doesn’t expect a leading zero-byte before an integer that is positive.
Here is an example of a real signature I got from the nitrokey (i have replaced most of each integer with x in order to more easily read the bytes that matter):
30 44
02 20 0059 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
02 20 22B4 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Both integers are 32 bytes long. Only the first integer has been prefixed with a zero-byte.
The first byte is 0x30 as expected. And the second byte 0x44 is the correct length for the data.
The first integer starts with 0x0059 - this is what is causing the python library (a call to ecdsa.util.sigdecode_der() function) to throw error UnexpectedDER(“Invalid encoding of integer, unnecessary zero padding bytes”).
My understanding is that the leading-zero should only exist if the next byte does not have it’s most-significant bit set - but 0x59 does not.
I created a test script in order to find this error, so maybe i am extracting the DER signature incorrectly? or maybe the nitrokey and python-ecdsa differ on the DER format? The problem only occurs occasionally - maybe 1 in 250 when i looped the code below.
while (true) {
var crypto = km.sc.getCrypto();
var dat = source.key.crypto.generateRandom(32);
var rawsig = crypto.sign(source.key, Crypto.ECDSA_SHA256, dat);
var sig = new ByteString(rawsig.toString().replace(/ /g, ""), HEX);
var xlen = sig.byteAt(3);
var xbytes = sig.bytes(4, xlen);
var ylen = sig.byteAt(4 + xlen + 1);
var ybytes = sig.bytes(6 + xlen, ylen);
if (xbytes.byteAt(0) == 0x00 && ((xbytes.byteAt(1) & (1 << 7)) == 0) ) {
throw new Error("Found unneccessary leading zero byte in integer X: " + h);
}
if (ybytes.byteAt(0) == 0x00 && ((ybytes.byteAt(1) & (1 << 7)) == 0) ) {
throw new Error("Found unneccessary leading zero byte in integer Y: " + h);
}
}
Thanks
Doug