I am trying to implement cryptographic algorithms on elliptic curve in Java Card.
First, I implemented it on 256bits elliptic curve (the NIST one) and it worked well.
Now I want to test it on a 512bits curve (and not 521 like the NIST one). My card support this size and I found a database of elliptic curves (well defined for cryptography) of this size. But I am encountering a strange problem...
When I try to initialize my key:
ECPublicKey pubKey = (ECPublicKey) KeyBuilder.buildKey(
KeyBuilder.TYPE_EC_FP_PUBLIC, (short) 0x0200, false);
pubKey.setFieldFP(new byte[] { (byte) 0x25, (byte) 0x37,
(byte) 0xD2, (byte) 0x9C, (byte) 0x8B, (byte) 0xFE,
(byte) 0x7D, (byte) 0x9F, (byte) 0x48, (byte) 0x98,
(byte) 0xF7, (byte) 0x60, (byte) 0xF8, (byte) 0x7D,
(byte) 0xBF, (byte) 0x63, (byte) 0x90, (byte) 0x6E,
(byte) 0x28, (byte) 0x99, (byte) 0x0A, (byte) 0x27,
(byte) 0x0C, (byte) 0xA6, (byte) 0x15, (byte) 0xD9,
(byte) 0x1D, (byte) 0xC4, (byte) 0x89, (byte) 0xA8,
(byte) 0xD0, (byte) 0xA1, (byte) 0xA0, (byte) 0xE7,
(byte) 0x52, (byte) 0x43, (byte) 0xB0, (byte) 0x39,
(byte) 0x01, (byte) 0x6A, (byte) 0x61, (byte) 0x43,
(byte) 0x5C, (byte) 0xA5, (byte) 0x91, (byte) 0xE9,
(byte) 0x4B, (byte) 0x1A, (byte) 0xF7, (byte) 0x60,
(byte) 0xC9, (byte) 0xAE, (byte) 0xE2, (byte) 0xCE,
(byte) 0xE0, (byte) 0x15, (byte) 0x53, (byte) 0x51,
(byte) 0x1C, (byte) 0x93, (byte) 0x0E, (byte) 0xF3,
(byte) 0xBA, (byte) 0x0B }, (short) 0x0000, (short) 0x0040);
The function setFieldFP
raises a CryptoException
with the reason code ILLEGAL_VALUE
which means that the key length doesn't match... But it does (0x0200
is the size of the curve in bits and 0X0040
is the length of the prime in bytes)!
I said it is really strange because if I try with the following value:
ECPublicKey pubKey = (ECPublicKey) KeyBuilder.buildKey(
KeyBuilder.TYPE_EC_FP_PUBLIC, (short) 0x0200, false);
pubKey.setFieldFP(new byte[] { (byte) 0xFF, (byte) 0xFF,
(byte) 0xFF, (byte) 0xFF, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0xFF, (byte) 0xFF,
(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
(byte) 0xFF, (byte) 0xFF, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0xFF, (byte) 0xFF,
(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
(byte) 0xFF, (byte) 0xFF}, (short) 0x0000, (short) 0x0040);
It works fine...
So I have to conclude that the CryptoException
that is raised doesn't really concern the size of the parameter because, in the two cases, the size is the same...
So what? Does my card only support elliptic curve on specific fields? Has someone ever encountered this kind of problem?
Your prime is not big enough. For curves over F(p) of 512 bit you should use 512 bit primes. Your first byte,
(byte) 0x25
, however starts with a hex digit2
. That means that the first byte first starts with 2 binary digits set to0
, meaning that you've defined a 512 - 2 = 510 bit prime.Please use only well defined curves, such as the NIST P521 curve or the BrainpoolP512r1 curve.