2

I am signing some data on a Javacard applet, then verifying it in java on my PC. To test this I have a message I know should verify, but when running my code verification fails.

This is my code:

//message = byte array of message from java card
//signature = byte array of signature from java card

BigInteger bigIntX = new BigInteger(1, xArray);
BigInteger bigIntY = new BigInteger(1, yArray);
boolean verified = false;

ECPoint w = new ECPoint(bigIntX, bigIntY);

KeyFactory newKeyFact = KeyFactory.getInstance("EC");
ECNamedCurveParameterSpec paramSpec = ECNAMEDCurveTable.getParameterSpec("secp256r1");
ECParameterSpec params = new ECNamedCurveSpec("secp256r1", paramSpec.getCurve(), paramSpec.getG(), paramSpec.getN(), paramSpec.getH());
ECPublicKey ecPublicKey - (ECPublicKey) newKeyFact.generatePublic(new ECPublicKeySpec(w, params));

Signature sig = Signature.getInstance("SHA256withECDSAinP1363Format");
sig.initVerify(ecPublicKey);
sig.update(message);
verified = sig.verify(signature);

if (verified) {
//print True
} else {
//print false
}

verified never gets set to true, even though I know this message should verify fine. Am I re-constructing the key wrong? Or is there something else I'm missing?

This is my javacard code where the signature is generated:

KeyPair key = new KeyPair(KeyPair.ALG_EC_FP, KeyBuilder.LENGTH_EC_FP_256);

ECPublicKey pubKey = (ECPublicKey) key.getPublic();
ECPrivateKey privKey = (ECPrivateKey) key.getPrivate();
initDomainParams(pubKey);
initDomainParams(privKey); //initDomainParams is just where I set A, B, G, R and K to the secp256r1 curve parameters using setA, setB etc

key.genKeyPair();
Signature sig = Signature.getInstance(Signature.ALG_ECDSA_SHA_256, false);
sig.init(key.getPrivate(), Signature.MODE_SIGN);
sig.sign(srcArr, srcoffset, srclength, destArr, destoffset);

LozCodes
  • 109
  • 8
  • @Robert updated to add in my code when I get bigIntX and bigIntY - this may be when I'm going wrong. Is there a way of interpreting them as unsigned? – LozCodes May 12 '22 at 09:45
  • Is your signature in P1363 format (can be checked by the length)? – Topaco May 12 '22 at 09:50
  • @LozCodes BigInteger creation already looks good. The `1` parameters makes it positive/unsigned. – Robert May 12 '22 at 09:56
  • @Topaco I believe so - how can I check? – LozCodes May 12 '22 at 09:57
  • @Robert Thank you! I thought that was what the 1 was doing but when you asked I wasn't sure! – LozCodes May 12 '22 at 09:58
  • @Topaco x and y are 32 bytes each – LozCodes May 12 '22 at 10:09
  • I refer to the length of `signature`. – Topaco May 12 '22 at 10:16
  • @Topaco sorry - signature is 72 bytes long – LozCodes May 12 '22 at 10:17
  • 1
    This looks like ASN.1/DER format. Check if this format is supported (e.g. `SHA256withECDSA`), otherwise you can explicitly convert the signature from ASN.1/DER to P1363, see [here](https://crypto.stackexchange.com/q/57731/94390)). – Topaco May 12 '22 at 10:29
  • @Topaco Thank you - I was originally trying to use ```Signature.getInstance("SHA256withDSA")``` but gEt an 'Invalid encodinf for signature' exception. – LozCodes May 12 '22 at 10:42
  • 1
    Is your 72-byte signature in the pattern 0x30 0x46 0x02 0x21 0x00 (32 bytes) 0x02 0x21 0x00 (32 bytes)? If so it's valid ASN.1 DER; if not it's either wrong, damaged, or something else. – dave_thompson_085 May 12 '22 at 11:03
  • The question post doesn't contain any info on the Java Card generated signature, so I'm voting to close until this detail has been added. – Maarten Bodewes May 12 '22 at 11:21
  • 1
    Note that SHA256withDSA is not the same as SHA256with**EC**DSA. – Topaco May 12 '22 at 11:25
  • @Topaco sorry yes - I was using SHA256withECDSA, that was a typo – LozCodes May 12 '22 at 11:28
  • Have you checked if the signature is as described in the [linked post](https://crypto.stackexchange.com/q/57731/94390) or in dave_thompson_085's comment? – Topaco May 12 '22 at 11:36
  • @dave_thompson_085 My signature is in the format you described/described here: https://crypto.stackexchange.com/q/57731/94390 – LozCodes May 12 '22 at 12:32
  • @Topaco yes it is – LozCodes May 12 '22 at 12:34
  • @Topaco I have checked the message, keys and they do seem to be consistent. How can I check that the signature is a valid secp256r1 signature? – LozCodes May 12 '22 at 13:20
  • Verify the signature e.g. with a code or tool that is known to work, e.g. https://8gwifi.org/ecsignverify.jsp (expects an X.509 PEM key for verifying). – Topaco May 12 '22 at 13:34
  • Could you just post the hex encoded signature? – Maarten Bodewes May 12 '22 at 13:34
  • @MaartenBodewes the hex signature is 30 44 02 20 0E 06 F0 B0 F9 AB 55 C5 C7 3B E7 D5 D2 2E 38 EF 91 62 47 10 FD CF 3F 46 AC 4A 81 85 C1 E7 4E 21 02 20 1A 99 2C 4F D9 1E 2E 03 05 EC E5 FB 5D 5C A2 25 4C 3D 1F 7E 0D 10 09 A7 D0 95 F7 AB 9A 1E A4 19 00 00 – LozCodes May 12 '22 at 13:40
  • The last two 0x00 bytes do not comply with the described format. – Topaco May 12 '22 at 13:43
  • @Topaco should the format of all EC signatures be as in the linked post? For example with the curve K-163 or K-233? – LozCodes Jun 08 '22 at 12:45
  • The two formats (ASN.1/DER and P1363) are generally valid for ECDSA. – Topaco Jun 08 '22 at 20:11

0 Answers0