1

I have an issue with verification of a ECDSA Signature made on javacard. I am trying to verify the signature in Javascript(Elliptic) but the verification always fails.

My applet(javacard) looks like:

//initialization
ecdsa = Signature.getInstance(Signature.ALG_ECDSA_SHA_256, false);
eccKey=SecP256k1.newKeyPair(); //in SecP256k1 the p,a,b,g,r,k are set
eccKey.genKeyPair();

//singing method
ecdsa.init(eccKey.getPrivate(), Signature.MODE_SIGN);

//Generates the signature of all input data.
short lenTmp = ecdsa.sign(buffer, ISO7816.OFFSET_CDATA, (short)1, buffer, 
(short)0);
//I tried also to sigh precomputed hash - same result
/*short lenTmp = ecdsa.signPreComputedHash(buffer, ISO7816.OFFSET_CDATA, 
len, buffer, (short)0); */

apdu.setOutgoingAndSend((short)0, lenTmp);

I get a private key (e.g. : 3E05E289911E66A8153EE9C15A0AFC109C49207DB9DC4656CC4D092323EA65BC)

When I sign a message (e.g : 0x01)

I get the signature in DER format: 304402205F376BB2B2D48BBB0275099C3B9591F18ECA424DD953EB27FDE37BA819B98F980220539A85B91491E977F6B31B5A76BEF6805BBC3B6481A51C23B9E7C6F39FB70569

Also its verification is successful on javacard.. But when I try to verify it on nodejs, it always fails. My code looks like:

let elliptic = require('elliptic');
let ec = new elliptic.ec('secp256k1');
let keyPair = ec.keyFromPrivate("3E05E289911E66A8153EE9C15A0AFC109C49207DB9DC4656CC4D092323EA65BC");
let privKey = keyPair.getPrivate("hex");
let pubKey = keyPair.getPublic();
let signature = "304402205F376BB2B2D48BBB0275099C3B9591F18ECA424DD953EB27FDE37BA819B98F980220539A85B91491E977F6B31B5A76BEF6805BBC3B6481A51C23B9E7C6F39FB70569";
let msg = 0x01;
let validSig = ec.verify(msg, signature, pubKey);
console.log("Signature valid?", validSig);//returns always false

Also, if I sign the same message with the same key on nodejs, the verification is successful.

Moreover, I noticed that the signature is always different in javacard, while the signature on elliptic is always the same, maybe it always chosses the same random k.

1 Answers1

1

This is most likely caused due to the fact that standard ecdsa libraries in java/go/python/etc. generate the signature der encoded where as the javascript library simply concatenates the R and S values of the signature. Here is how I deal with this issue in my own library HERE. Sorry the example is golang to typescript, but hopefully you can reverse engineer this to java/javascript. Event within Node.js this issue exists. Here is a LINK to a discussion that ultimately helped me figure out how to breach the gap between the implementations within my own work.

  • I made a signature also on javascript(using same private key and message) and the result is also in DER format(not only r and s concatenated), but I get the same signature always: `304402206d55364f9eff56dcff626467920ea8c2fed44653009cde369546cc98da3b2be00220086abcc4a127c5ac1dcb5d7c4da51fca96a75e70cdeeb6bc746010345a691beb` – Alexandru Maceasa May 04 '19 at 04:33
  • Hmmm... I remember having the same issue when I tried using the `elliptic` library. Ultimately I did solve that issue. Instead I decided to simply rely on the browser builtin `crypto.subtle` library. Sorry can't help with this one. Generally speaking though, the signature should always be different because of a random factor inside of it. So if it is always the same value, there is definitely an issue. If you end up swapping to `subtle.crypto` feel free to bug me for more questions. I did loads of work with the spec for it and understand it pretty well. – Konstantin Itskov May 06 '19 at 14:58