Reputation: 51
i have self-signed certificate signed by SHA1withECDSA algorithm using BouncyCastle. Under BC i can verify it easily, but when i`m doing it on JavaCard it send me false everytime(Curve secp192r1 from NIST). Certificate hold sign in plain (non X9.62 mean just r+s without any TAGs).
There is my code to verify it (with values putted as constant - for tests of course).
byte[] certdata = {...}
Signature signature = Signature.getInstance(Signature.ALG_ECDSA_SHA, false);
ECPublicKey ecpk = (ECPublicKey) KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PUBLIC, KeyBuilder.LENGTH_EC_FP_192, true);
ecpk.setA(new byte[]{...}, (short)0, (short)0x0018);
ecpk.setB(new byte[]{...}, (short)0, (short)0x0018);
ecpk.setG(new byte[]{...}, (short)0, (short)0x0031);
//Point format: uncompressed tag(0x04), x, y
ecpk.setK((short)0x0001);
ecpk.setR(new byte[]{}, (short)0, (short)0x0018);
ecpk.setW(new byte[]{}, (short)0, (short)0x31);
ecpk.setFieldFP(new byte[]{}, (short)0, (short)0x0018);
signature.init(ecpk, Signature.MODE_VERIFY);
boolean result = signature.verify(certdata, (short)0, (short)certdata.length, signtab, (short)0, (short)signtab.length);
if(result) ISOException.throwIt((short)0x0001);
else ISOException.throwIt((short)0x0002);
}
'...' instead of bytes for clear view (192bits curve can do big mess).
Certificate with TAGS explanation on pastebin:
Thanks for any help
sevar
edit: New tests: All tests re on same data (PublicKey, PrivateKey, Message to be signed) sign is randomized so i ll use 2 sign (signT - sign generated by Terminal (BC), signC - sign generated by Chip)
signT cant be verified on CHIP but can be verified on Terminal. signC is verified on CHIP & Terminal
so I checked cross between API
Cross Relation directed to BC works well
Cross Relation directed to CHIP isn't work
pair of key generated well because when i put PrivateKey and PublicKey generated by BC to CHIP, then signature generated on the CHIP can be verified by CHIP.
I have no idea what i should check now. Problem probably can be with filling array in ECDSA step e = SHA1(Message). Whats happen with array after hash(hash is shorter than curve and card needs to declare size of array before copy)
Upvotes: 5
Views: 1860
Reputation: 167
I had a problem with verifinge a ECDSA singature (generated on JavaCard 192r1) using BouncyCastle and i found a solution. I hope that it will be useful
Verify javacard signature ALG_ECDSA_SHA on bouncy castle
Upvotes: 0
Reputation: 5661
Signing and verification of ECDSAwithSHA-1 with Prime192v1 from Bouncy Castle to JavaCard works fine for me.
Your problem is probably format of the signature itself.
Signature is a DER encoded structure, it is a sequence (tag 0x30) of two integers (tag 0x02). In JavaCard, 56 bytes are always expected: two coordinates of length 25 plus 6 bytes of DER headers. JavaCard always expects leading zeros in each coordinate. However, BC often produces signatures without leading zeros in coordinates, so the signature can be shorter than 56 bytes and that is why JavaCard is confused.
The opposite direction is always OK, because BC can handle leading zeros, although it does not add them when creating signature.
What you should do: wrap the BC signing mechanism with your own code and ALWAYS add leading zeros to coordinates in your BC signature. If you do so, you will be able to verify the signature both in BC and JavaCard.
I would like to post my code, but unfortunately it is a part of a commercial security project...
Upvotes: 0