Java Card小程序响应APDU命令返回6700错误的原因排查
Java Card小程序返回6700错误的排查与修复
你的Java Card小程序在处理APDU命令00 40 00 00 0A 0102030405060708090A时返回6700(命令格式/长度错误),该命令符合Case2格式(带Lc和数据字段),问题出在APDU处理代码的判断逻辑上。
问题核心分析
- 返回值判断错误:在INS=0x40的处理分支中,
apdu.setIncomingAndReceive()方法返回实际接收到的数据字节数,你的命令Lc为0x0A(10字节),所以该方法返回值是10,但代码中错误判断byteRead != 1,直接触发了SW_WRONG_LENGTH。 - 常量值校验:需确认
PayloadSize常量的值是否为10,如果与命令中Lc的0x0A不一致,第一个判断numBytes != PayloadSize也会抛出6700错误。
修复后的代码
public void process(APDU apdu) { if (selectingApplet()) { return; // 返回9000表示SELECT成功 } byte[] buf = apdu.getBuffer(); switch (buf[ISO7816.OFFSET_INS]) { case (byte) 0x40: byte numBytes = buf[ISO7816.OFFSET_LC]; short byteRead = apdu.setIncomingAndReceive(); // 校验指定长度与实际接收长度是否匹配预期PayloadSize if (numBytes != PayloadSize || byteRead != PayloadSize) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); // 使用固定偏移量ISO7816.OFFSET_CDATA定位数据起始位置 Util.arrayCopy(buf, ISO7816.OFFSET_CDATA, data, (short) 0, PayloadSize); break; case (byte) 0x41: Util.arrayCopy(data, (short) 0, buf, ISO7816.OFFSET_CDATA, PayloadSize); apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, PayloadSize); break; default: ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); } }
补充说明
setIncomingAndReceive()方法对于Case2类型的APDU命令,会读取Lc指定的全部数据字节,返回值等于Lc的数值,因此判断时应与预期的PayloadSize或numBytes比对,而非固定值1。ISO7816.OFFSET_CDATA是Case2命令中数据字段的固定起始偏移(偏移量为5),无需从缓冲区中读取该值,直接使用常量即可避免潜在错误。
内容的提问来源于stack exchange,提问作者Alan Kazbekov
相关产品推荐
相关产品推荐

