第一个JAVA卡应用

2014-11-26 15:37:21
admin
4912
最后编辑:admin 于 2014-12-11 15:27:27
简介:javacard.framework.Applet RandomData JAVA卡应用 JAVA卡Applet JAVA卡 JavaCard GP GlobalPlatform install select process deselect
每一个JAVA卡应用都必须继承javacard.framework.Applet抽象类,首先定义它的构造函数和功能APDU相关函数;然后是应用生命周期的管理方法:install()、select()、process()、deselect();最后它定义辅助的私有方法。我们重点描述一下生命周期的管理方法:

install()
每次安装应用时调用一次,负责应用的初始化、空间分配、修改注册表等。(必须实现)
select()
每次发送选择APDU时调用一次,负责应用执行前的初始化、设置安全属性、设置交易属性等。
process()
每次发送APDU时执行一次(包括选择APDU),负责处理APDU逻辑。(必须实现)
deselect()
每次发送选择APDU时自动调用上一个选择的应用的deselect()函数,负责运行后的清理工作。一般不需要实现该函数,因为process后一般会马上断电,这时候根本就不会调用deselect()函数,因此在这里进行清理工作很危险。


一、实现第一个应用 - 重JAVA卡中获取用户请求长度的随机数

JAVA源码下载地址:RandomNumberApplet.java


第一步:引入需要的类库,并继承Applet抽象类。
import javacard.framework.*;
import javacard.security.*;
public class RandomNumberApplet extends Applet {
}

第二步:实现构造函数,初始化随机数生成器randomData成员。
private RandomData randomData;
public RandomNumberApplet() {
  randomData = RandomData.getInstance(RandomData.ALG_SECURE_RANDOM);
}

第三步:实现install回调函数,构造RandomNumberApplet对象,并修改JAVA卡注册表。
public static void install(byte[] bArray, short bOffset, byte bLength) {
  // GP-compliant JavaCard applet registration
  new RandomNumberApplet().register(bArray, (short) (bOffset + 1),
      bArray[bOffset]);
}

第四步:实现process回调函数,处理APDU指令,如下为处理0x84的取随机数指令。

此处我们谈一下select回调函数(一般不重载):发送选择APDU时,先调用select函数,然后调用process函数;而JAVA卡提供了判断是否处于选择状态的函数,所以select的函数功能基本可以挪到下面黑体部分实现。唯一例外的是如果想要拒绝应用选择,还是必须放在select里面进行return false操作。


javacard.framework.APDU类处理通信相关操作:
1、byte[] buf = apdu.getBuffer();卡片接收的数据存储在该缓冲区。
2、apdu.setOutgoingAndSend((short)0, randomLen);卡片发送数据给用户,每个APDU过程只能调用一次。另外process函数会自动返回9000状态值。
3、ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);发送其它SW1-SW2状态值。

public void process(APDU apdu) {

  // Good practice: Return 9000 on SELECT
  if (selectingApplet()) {
    return;
  }
  byte[] buf = apdu.getBuffer();
  switch (buf[ISO7816.OFFSET_INS]) {
  case (byte) 0x84:
    short randomLen = buf[4];
    randomData.generateData(buf, (short)0, randomLen);
    apdu.setOutgoingAndSend((short)0, randomLen);
    break;
  default:
    // good practice: If you don't know the INStruction, say so:
    ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
  }
}


二、运行第一个应用 - 重JAVA卡中获取用户请求长度的随机数

CAP文件的AID=00000000000100
RandomNumberApplet类的AID=00000000000101
RandomNumberApplet类实例的AID=00000000000101
CAP文件下载地址:random.cap

脚本下载地址:random.jcsh

请将脚本里面的读卡器配置和CAP文件位置情况进行修改!


第一步:安装到JAVA卡(JCOP操作)
1、连接到读卡器(需要修改):/terminal "winscard:4|SCM Microsystems Inc. SDI011G Contactless Reader 0"
2、选择Card Manager管理应用:/card -a a000000003000000 -c com.ibm.jc.CardManager
3、进行认证授权以获取权限:auth
4、如果已经安装过则先删除:delete -r 00000000000100
5、上传应用(需要修改):upload -c -b 250 "D:\eclipse\workspace\demo\bin\random\javacard\random.cap"
6、安装应用(可安装多个实例,只要实例AID不冲突):install -i 00000000000101  -q C9#() 00000000000100 00000000000101
7、显示安装结果:ls


第二步:运行随机数应用(JCOP操作)
1、选择随机数应用实例:
/select 00000000000101
2、发送取随机数APDU:
取8字节随机数:/send 0084000008
返回结果(状态9000):BA7996BBF905B6529000
取4字节随机数:/send 0084000004
返回结果(状态9000):6CC4E2839000


    发表评论
    评论通过审核之后才会显示。