因项目需要,利用APDU通信协议在ME手机端和卡端进行通讯。在实践的过程中遇到一些问题,先记录如下。
APDU协议,即是智能卡与读写器间的应用层协议,在ISO7816-4[7]中定义了该协议的结构格式。APDU数据有两种结构,读写器使用的APDU结构为命令APDU,C-APDU(Command APDU),智能卡方面使用的APDU结构为响应APDU,R-APDU(Reponse APDU)。
命令APDU
必选部分:CLA, INS, P1, P2
可选部分:LC, 数据段, LE
CLA确定APDU的类别,INS确定要执行的指令,P1和P2是参数。
LC确定数据段的长度,数据段是发送到智能卡上的数据,LE确定读写器期待智能卡响应的字节数。
响应APDU
可选部分:数据段
必选部分:SW1, SW2
数据段的长度由命令APDU的LE确定。
SW1和SW2是状态字。
卡侧APDU编程实践
JAVACARD有一系列APDU处理的方法可以调用,详情可以查看相应的说明文档。先简单记录下我在实践过程中遇到的一些问题,及相应的答案。
在处理一个APDU命令前,首先要调用getBuffer命令取得APDU缓冲区数组的引用,通过该数组的引用,即可访问APDU缓冲区数组的内容。
public voidprocess(APDU apdu) {byte[] buffer =apdu.getBuffer();switch(buffer[ISO7816.OFFSET_INS]) {
}
}
首先要注意两点,第一:其中取得缓冲数组的引用给buffer时,注意buffer需在方法中定义,即定义为局部数组。第二:此时获得的buffer数组中仅仅包含APDU的命令头,即CLA, INS, P1, P2,P3,不包括后续的数据(即P3后的数据)。如需接受完整的APDU指令,需要利用
byte buffer[]=apdu.getBuffer();short bytesRead=apdu.setIncomingAndReceive();
注意apdu.setIncomingAndReceive()返回数据长度,为命令头后面的数据长度,即LC的值。