2

我正在尝试在 JavaCard(Eclipse 4.4.2、JC 2.2.1)中实现 ECDSA。我的卡是金雅拓 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() 返回 0x80206F00 (Unknown ISO7816 error: 0x6F00)),但是当我环绕它,它不会返回错误(send_APDU() 返回 0x80209000 (9000: Success. No error.))。但是它必须转到 catch 块,因为 try 块中的其他三行没有被执行。

如何可视化错误消息?如果我使用ISOException.throwIt(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;
    }
}
4

1 回答 1

3

您的麻烦有两个可能的原因:

  1. 您的状态字不符合 ISO7816 推荐的状态字。尝试

    ISOException.throwIt((short) ((short) (0x9C00) | reason));
    

    代替

    ISOException.throwIt(reason);
    
  2. 在生成新密钥对之前,您忘记设置椭圆曲线的参数。您应该以这种方式生成您的 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

于 2015-04-07T06:11:31.553 回答