我试图让Elliptic Curve Diffie Hellman在JavaCard(版本2.2.1)上工作。
在JavaCard上,我现在有以下代码:
byte temp[] = new byte[100];
byte secret[] = new byte[100];
byte size = buf[ISO7816.OFFSET_LC];
Util.arrayCopy(buf, ISO7816.OFFSET_CDATA, temp, (byte) 0, size);
// the public key is in temp
short len = dh.generateSecret(temp, (byte) 0, size, secret, (byte) 0);
Util.arrayCopy(temp, (byte) 0, buf, ISO7816.OFFSET_CDATA, size);
//Util.arrayCopy(secret, (byte) 0, buf, ISO7816.OFFSET_CDATA, len);
apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, size);
我按如下方式初始化dh
:
keyPair = new KeyPair(KeyPair.ALG_EC_FP, KeyBuilder.LENGTH_EC_F2M_163);
keyPair.genKeyPair();
dh = KeyAgreement.getInstance(KeyAgreement.ALG_EC_SVDP_DH, false);
dh.init(keyPair.getPrivate());
所有这一切似乎都有效,除了dh.generateSecret
调用,其中applet似乎只是崩溃了。如果我退出呼叫,并返回其他数据,这很好用。我在其中导入终端发送的数据。在终端,我有以下内容:
// generate an ecdh keypair
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
keyGen.initialize(163);
KeyPair keyPair = keyGen.generateKeyPair();
// initialize DH
KeyAgreement dh = KeyAgreement.getInstance("ECDH");
dh.init(keyPair.getPrivate());
//byte encKey[] = keyPair.getPublic().getEncoded();
// X9.62 encoding, no compression
int qLength = (163+7)/8;
byte[] xArr = ((ECPublicKey) keyPair.getPublic()).getW().getAffineX().toByteArray();
byte[] yArr = ((ECPublicKey) keyPair.getPublic()).getW().getAffineY().toByteArray();
byte[] enc2 = new byte[1+2*qLength];
enc2[0] = (byte) 0x04;
System.arraycopy(xArr, 0, enc2, qLength - xArr.length, xArr.length);
System.arraycopy(yArr, 0, enc2, 2* qLength - yArr.length, yArr.length);
byte res[] =send((byte) 0x00, enc2).getData();
我尝试过几件事。现在,发送公钥的代码尝试按照JavaCard文档的指定以X9.62编码(未压缩)对其进行编码。但是,我也尝试了默认的encode
方法,它可以得到完全相同的结果。
我似乎无法从JavaCard中获得有关出错的错误。有谁知道出了什么问题?或者有没有人有关于如何在JavaCard上进行密钥交换的工作示例?
答案 0 :(得分:0)
正如vojta已经指出的那样:
keyPair = new KeyPair(KeyPair.ALG_EC_FP, KeyBuilder.LENGTH_EC_F2M_163);
只是尝试生成一个密钥对,它可能工作到一定程度。但是Fp曲线与F2m曲线不同,据我所知,没有163位Fp曲线(据我所知)。
这意味着你从未真正安装域参数,除非你自己生成了域名参数,我不会这么说。
使用具有已知密钥长度的Fp曲线并设置参数,至少对于公钥(对于JCOP卡,您可能还必须为私钥设置它们)。您通常使用224位密钥或更高密钥来保证安全。