I have generated an ECDSA signature in Java and I would like to get the R and S values from it in order to have the COSE encoded signature. It is my understanding that the signature I have generated is DER encoded (by default using bouncyCastle). I properly retrieve the R and S values when I used P-256 curve (SHA256withECDSA).
I have some issues parsing the signature from one encoding to another when I use other curves (P-521, P-384).
Here after is how I parse it :
public static byte[] extractRandSToCose(byte[] signature) {
if (signature[0] == 0x30) {
//parse R
int rSize = signature[3];
BigInteger rBigInt = new BigInteger(Arrays.copyOfRange(signature, 4, rSize+4));
//strip out sign byte 0x00
byte[] r = toByteArrayUnsigned(rBigInt);
//parse S
int sSize = signature[5 + rSize];
int index = rSize + 6;
BigInteger sBigInt = new BigInteger(Arrays.copyOfRange(signature, index, index+sSize));
//strip out sign byte 0x00
byte[] s = toByteArrayUnsigned(sBigInt);
return Bytes.concat(r,s);
}
return null;
}
public static byte[] toByteArrayUnsigned(BigInteger bigInteger) {
byte[] extractedBytes = bigInteger.toByteArray();
int skipped = 0;
boolean skip = true;
for (byte b : extractedBytes) {
boolean signByte = b == 0x00;
if (skip && signByte) {
skipped++;
continue;
} else if (skip){
skip = false;
}
}
extractedBytes = Arrays.copyOfRange(extractedBytes, skipped, extractedBytes.length);
return extractedBytes;
}
I dont get what I am doing wrong.
PS: Those methods works from time to time. It works everytime for P-256 (whether the DER signature is 70 71 or 72 bytes long and properly gives me a 64 byte long Cose signature), P-384 (same for 102, 103 104 byte long and properly gives me a 96 byte long cose signature) but only works half the time for P-521 (138, 139, 140 byte long and even when it does the cose signature is only 31 byte long....)
{hash}withECDSAinP1363Format
did the trick ! Thank you ! I didn't even needed to read all those specs to see how to parse it...