获取JavaCard中CryptoException的原因
Get the reason of CryptoException in JavaCard
我正在尝试在 JavaCard(Eclipse 4.4.2、JC 2.2.1)中实现 ECDSA。我的卡是 Gemalto IDCore 3010,或者至少应该是(在检查 ATR 代码后,它看起来像是 WM GX4 72 DHS TSA...)。
无论如何,如果我不使用 try and catch 包围 objECDSAKeyPair = new KeyPair(KeyPair.ALG_EC_FP, KeyBuilder.LENGTH_EC_FP_192) 行我得到未知错误 (send_APDU() returns 0x80206F00 (Unknown ISO7816 error: 0x6F00)),但是当我包围它时,它 returns 没有错误(send_APDU() returns 0x80209000(9000:成功。没有错误。))。但是它必须转到 catch 块,因为 try 块中的其他三行不会被执行。
如何可视化错误消息? 如果我使用 ISOException.throwIt(原因),我得到 与智能卡的通信错误。请重试。 多次。
在 this 线程中它建议 byte reason = c.getReason() 代码,但它不会工作,即使我投右侧到字节。
谢谢!
这是我的代码的相关部分。
public class ECDSATestApplet extends Applet {
private final static byte CLS = (byte) 0xE0;
private final static byte NOOP = (byte) 0x00;
private final static byte GEN = (byte) 0x01;
...
private final static byte[] HELLO_WORLD = new byte[] { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
private ECPrivateKey objECDSAPriKey = null;
private ECPublicKey objECDSAPubKey = null;
private KeyPair objECDSAKeyPair = null;
private Signature objECDSASign = null;
final static short BAS = 0;
private ECDSATestApplet() {
}
public static void install(byte[] bArray, short bOffset, byte bLength) {
new ECDSATestApplet().register();
}
public void process(APDU apdu) {
if (this.selectingApplet())
return;
byte buffer[] = apdu.getBuffer();
if (buffer[ISO7816.OFFSET_CLA] != CLS)
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
switch (buffer[ISO7816.OFFSET_INS]) {
case NOOP:
break;
case GEN:
try {
// ------- ERROR LINE -------
objECDSAKeyPair = new KeyPair(KeyPair.ALG_EC_FP, KeyBuilder.LENGTH_EC_FP_192);
// objECDSASign = Signature.getInstance(Signature.ALG_ECDSA_SHA, false);
// objECDSAKeyPair.genKeyPair();
// objECDSAPriKey = (ECPrivateKey) objECDSAKeyPair.getPrivate();
// objECDSAPubKey = (ECPublicKey) objECDSAKeyPair.getPublic();
apdu.setIncomingAndReceive();
Util.arrayCopyNonAtomic(HELLO_WORLD, (short) 0, buffer, (short) 0, (short) HELLO_WORLD.length);
apdu.setOutgoingAndSend((short) 0, (short) HELLO_WORLD.length);
} catch (CryptoException c) {
short reason = c.getReason();
// ISOException.throwIt(reason);
}
break;
}
return;
}
}
您的困扰可能有两个原因:
您的状态词不符合 ISO7816 推荐的状态词。尝试
ISOException.throwIt((short) ((short) (0x9C00) | reason));
而不是
ISOException.throwIt(reason);
您忘记在生成新密钥对之前设置椭圆曲线的参数。您应该以这种方式生成您的 EC 密钥对:
KeyPair keyPair = new KeyPair(KeyPair.ALG_EC_FP, KeyBuilder.LENGTH_EC_FP_192);
ECPrivateKey privKey = (ECPrivateKey) keyPair.getPrivate();
ECPublicKey pubKey = (ECPublicKey) keyPair.getPublic();
initDomainParams(pubKey);
initDomainParams(privKey);
keyPair.genKeyPair();
哪里
private void initDomainParams(ECKey key) {
key.setFieldFP(F, (short)0, (short)F.length);
key.setA(A, (short)0, (short)A.length);
key.setB(B, (short)0, (short)B.length);
key.setG(G, (short)0, (short)G.length);
key.setR(R, (short)0, (short)R.length);
}
使用您为签名选择的椭圆曲线的 F
、A
、B
、G
、R
参数。请在此处查看推荐曲线列表:http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf
我正在尝试在 JavaCard(Eclipse 4.4.2、JC 2.2.1)中实现 ECDSA。我的卡是 Gemalto IDCore 3010,或者至少应该是(在检查 ATR 代码后,它看起来像是 WM GX4 72 DHS TSA...)。
无论如何,如果我不使用 try and catch 包围 objECDSAKeyPair = new KeyPair(KeyPair.ALG_EC_FP, KeyBuilder.LENGTH_EC_FP_192) 行我得到未知错误 (send_APDU() returns 0x80206F00 (Unknown ISO7816 error: 0x6F00)),但是当我包围它时,它 returns 没有错误(send_APDU() returns 0x80209000(9000:成功。没有错误。))。但是它必须转到 catch 块,因为 try 块中的其他三行不会被执行。
如何可视化错误消息? 如果我使用 ISOException.throwIt(原因),我得到 与智能卡的通信错误。请重试。 多次。
在 this 线程中它建议 byte reason = c.getReason() 代码,但它不会工作,即使我投右侧到字节。
谢谢!
这是我的代码的相关部分。
public class ECDSATestApplet extends Applet {
private final static byte CLS = (byte) 0xE0;
private final static byte NOOP = (byte) 0x00;
private final static byte GEN = (byte) 0x01;
...
private final static byte[] HELLO_WORLD = new byte[] { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
private ECPrivateKey objECDSAPriKey = null;
private ECPublicKey objECDSAPubKey = null;
private KeyPair objECDSAKeyPair = null;
private Signature objECDSASign = null;
final static short BAS = 0;
private ECDSATestApplet() {
}
public static void install(byte[] bArray, short bOffset, byte bLength) {
new ECDSATestApplet().register();
}
public void process(APDU apdu) {
if (this.selectingApplet())
return;
byte buffer[] = apdu.getBuffer();
if (buffer[ISO7816.OFFSET_CLA] != CLS)
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
switch (buffer[ISO7816.OFFSET_INS]) {
case NOOP:
break;
case GEN:
try {
// ------- ERROR LINE -------
objECDSAKeyPair = new KeyPair(KeyPair.ALG_EC_FP, KeyBuilder.LENGTH_EC_FP_192);
// objECDSASign = Signature.getInstance(Signature.ALG_ECDSA_SHA, false);
// objECDSAKeyPair.genKeyPair();
// objECDSAPriKey = (ECPrivateKey) objECDSAKeyPair.getPrivate();
// objECDSAPubKey = (ECPublicKey) objECDSAKeyPair.getPublic();
apdu.setIncomingAndReceive();
Util.arrayCopyNonAtomic(HELLO_WORLD, (short) 0, buffer, (short) 0, (short) HELLO_WORLD.length);
apdu.setOutgoingAndSend((short) 0, (short) HELLO_WORLD.length);
} catch (CryptoException c) {
short reason = c.getReason();
// ISOException.throwIt(reason);
}
break;
}
return;
}
}
您的困扰可能有两个原因:
您的状态词不符合 ISO7816 推荐的状态词。尝试
ISOException.throwIt((short) ((short) (0x9C00) | reason));
而不是
ISOException.throwIt(reason);
您忘记在生成新密钥对之前设置椭圆曲线的参数。您应该以这种方式生成您的 EC 密钥对:
KeyPair keyPair = new KeyPair(KeyPair.ALG_EC_FP, KeyBuilder.LENGTH_EC_FP_192); ECPrivateKey privKey = (ECPrivateKey) keyPair.getPrivate(); ECPublicKey pubKey = (ECPublicKey) keyPair.getPublic(); initDomainParams(pubKey); initDomainParams(privKey); keyPair.genKeyPair();
哪里
private void initDomainParams(ECKey key) { key.setFieldFP(F, (short)0, (short)F.length); key.setA(A, (short)0, (short)A.length); key.setB(B, (short)0, (short)B.length); key.setG(G, (short)0, (short)G.length); key.setR(R, (short)0, (short)R.length); }
使用您为签名选择的椭圆曲线的
F
、A
、B
、G
、R
参数。请在此处查看推荐曲线列表:http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf