java - ECDSA Signature in Javacard -
i'm implementing signing code using ecdsa in javacard.
my code outputs 0x0003(no_such_algorithm) in exception part means card not support algorithm. don't understand because vendor told me supports ecc. concluded don't know how sign ecdsa , want know that.
here full source code
package myecdsa; import javacard.framework.*; import javacard.security.*; import javacardx.crypto.*; public class myecdsa extends applet{ private byte[] plaintext ; private ecprivatekey objecdsaprikey=null; // object ecdsa private key private ecpublickey objecdsapubkey=null; // object ecdsa public key private keypair objecdsakeypair=null; // object ecdsa key pair private signature objecdsasign=null; // object ecdsa signature final static short bas = 0; public static void install(byte[] barray, short boffset, byte blength){ new myecdsa(barray, boffset, blength); } private myecdsa(byte barray[], short boffset, byte blength){ plaintext = new byte[0x100] ; // data file util.arrayfillnonatomic(plaintext, bas, (short)0x100, (byte)0); register(); } //====================================================================================== public void process(apdu apdu){ byte buf[] = apdu.getbuffer(); switch(buf[1]) { //-------------------------------------------------------- case (byte)0xa4: break; case (byte)0x46: // create ecdsa keys , pair try { // <<<<<<<<<<<<<<<< here problem >>>>>>>>>>>>>>>>> objecdsakeypair = new keypair(keypair.alg_ec_fp, keybuilder.length_ec_fp_192); //objecdsakeypair = new keypair(keypair.alg_ec_f2m, keybuilder.length_ec_f2m_193); } catch(cryptoexception c) { short reason = c.getreason(); isoexception.throwit(reason); } isoexception.throwit((short)0x9999); // check // generate key pair objecdsakeypair.genkeypair(); // create signature object objecdsasign = signature.getinstance(signature.alg_ecdsa_sha, false); objecdsaprikey = (ecprivatekey)objecdsakeypair.getprivate(); objecdsapubkey = (ecpublickey)objecdsakeypair.getpublic(); break; case (byte)0x2e: short le = apdu.setoutgoing(); short ssignlen=0 ; // init private key objecdsasign.init(objecdsaprikey, signature.mode_sign); // sign data ssignlen = objecdsasign.sign(plaintext, bas, le, buf, bas); apdu.setoutgoinglength(ssignlen); apdu.sendbytes(bas, ssignlen); break; //-------------------------------------------------------- default: isoexception.throwit(iso7816.sw_ins_not_supported); } return; } }
and apdu command follows
[ card ] <== 00a4040007d4106509900090 [ card ] ==> 9000 [ card ] <== 0046000000 [ card ] ==> 0003
my development environment follows.
- os : windows 7
- jcdk ver 2.2.1
- jdk ver 1.4.2
- chip : nxp
- terminal : acr122 nfc contactless smart card reader
i've changed code set domain parameters. card still outputs same result(0x0003). here full source code.
package myecdsa; import javacard.framework.*; import javacard.security.*; import javacardx.crypto.*; public class myecdsa extends applet{ private byte[] plaintext ; private ecprivatekey objecdsaprikey=null; // object ecdsa private key private ecpublickey objecdsapubkey=null; // object ecdsa public key private keypair objecdsakeypair=null; // object ecdsa key pair private signature objecdsasign=null; // object ecdsa signature final static short bas = 0; final static byte[] secp192r1_p = { // 24 (byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff, (byte)0xfe,(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}; final static byte[] secp192r1_a = { // 24 (byte)0xfc,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff, (byte)0xfe,(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}; final static byte[] secp192r1_b = { // 24 (byte)0xb1,(byte)0xb9,(byte)0x46,(byte)0xc1,(byte)0xec,(byte)0xde,(byte)0xb8,(byte)0xfe, (byte)0x49,(byte)0x30,(byte)0x24,(byte)0x72,(byte)0xab,(byte)0xe9,(byte)0xa7,(byte)0x0f, (byte)0xe7,(byte)0x80,(byte)0x9c,(byte)0xe5,(byte)0x19,(byte)0x05,(byte)0x21,(byte)0x64}; final static byte[] secp192r1_s = { // 20 (byte)0xd5,(byte)0x96,(byte)0x21,(byte)0xe1,(byte)0xea,(byte)0x20,(byte)0x81,(byte)0xd3, (byte)0x28,(byte)0x95,(byte)0x57,(byte)0xed,(byte)0x64,(byte)0x2f,(byte)0x42,(byte)0xc8, (byte)0x6f,(byte)0xae,(byte)0x45,(byte)0x30}; final static byte[] secp192r1_g = { // 25 (byte)0x12,(byte)0x10,(byte)0xff,(byte)0x82,(byte)0xfd,(byte)0x0a,(byte)0xff,(byte)0xf4, (byte)0x00,(byte)0x88,(byte)0xa1,(byte)0x43,(byte)0xeb,(byte)0x20,(byte)0xbf,(byte)0x7c, (byte)0xf6,(byte)0x90,(byte)0x30,(byte)0xb0,(byte)0x0e,(byte)0xa8,(byte)0x8d,(byte)0x18,(byte)0x03}; final static byte[] secp192r1_n = { // 24 (byte)0x31,(byte)0x28,(byte)0xd2,(byte)0xb4,(byte)0xb1,(byte)0xc9,(byte)0x6b,(byte)0x14, (byte)0x36,(byte)0xf8,(byte)0xde,(byte)0x99,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff, (byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff}; final static short secp192r1_h = 1; //====================================================================================== public static void install(byte[] barray, short boffset, byte blength){ new myecdsa(barray, boffset, blength); } private myecdsa(byte barray[], short boffset, byte blength){ plaintext = new byte[0x100] ; // data file util.arrayfillnonatomic(plaintext, bas, (short)0x100, (byte)0); register(); } //====================================================================================== public void process(apdu apdu){ byte buf[] = apdu.getbuffer(); switch(buf[1]) { //-------------------------------------------------------- case (byte)0xa4: break; case (byte)0x46: // create ecdsa keys , pair try { // <<<<<<<<<<<<<<<< here problem >>>>>>>>>>>>>>>>> objecdsaprikey = (ecprivatekey)keybuilder.buildkey(keybuilder.type_ec_fp_private, keybuilder.length_ec_fp_192, false); isoexception.throwit((short)0x8888); // check objecdsapubkey = (ecpublickey)keybuilder.buildkey(keybuilder.type_ec_fp_public, keybuilder.length_ec_fp_192, false); // set ec domain parameters objecdsapubkey.setfieldfp(secp192r1_p, bas, (short)24); objecdsapubkey.seta(secp192r1_a, bas, (short)24); objecdsapubkey.setb(secp192r1_b, bas, (short)24); objecdsapubkey.setg(secp192r1_g, bas, (short)25); objecdsapubkey.setk(secp192r1_h); objecdsapubkey.setr(secp192r1_n, bas, (short)24); objecdsakeypair = new keypair(keypair.alg_ec_fp, keybuilder.length_ec_fp_192); } catch(cryptoexception c) { short reason = c.getreason(); isoexception.throwit(reason); // check } // on-card key generation process objecdsakeypair.genkeypair(); // obtain key references objecdsaprikey = (ecprivatekey)objecdsakeypair.getprivate(); objecdsapubkey = (ecpublickey)objecdsakeypair.getpublic(); // create signature object objecdsasign = signature.getinstance(signature.alg_ecdsa_sha, false); break; case (byte)0x2e: short le = apdu.setoutgoing(); short ssignlen=0 ; // init private key objecdsasign.init(objecdsaprikey, signature.mode_sign); // sign data ssignlen = objecdsasign.sign(plaintext, bas, le, buf, bas); apdu.setoutgoinglength(ssignlen); apdu.sendbytes(bas, ssignlen); break; //-------------------------------------------------------- default: isoexception.throwit(iso7816.sw_ins_not_supported); } return; } }
there no default ec domain parameters in java card. required create keypair
using ecpublickey
, ecprivatekey
domain parameters set (so point w , secret s may kept empty). after possible call genkeypair()
, @ least if card has support f(2m) or f(p) elliptic curve cryptography , key size specified.
added
note nxp jcop chips may require these parameters set public and private key. parameters should have either key size (for separate values) or uncompressed elliptic curve point. value of g in question seems compressed point. cofactor (for seth
) should have value 1.
note chips asymmetric coprocessor may support elliptic curves; not cards created / configured equally. contact vendor details.
Comments
Post a Comment