一、 简介
Javacard跨越上下文的对象访问。Javacard防火墙将一个applet的运行限定在它的被指定的上下文中。为了允许applet与其它的applet或JCRE进行交互,Javacard提供了一个上下文可以访问一个属于另一个上下文的对象。
提供了以下四种安全机制:
二、JCRE入口点对象
安全的Javacard系统中提供一种方法,使得非特权的用户(被限制在资源的一子集中)能够请求系统服务,这些服务将由“JCRE入口点对象”来完成。这些JCRE是属于JCRE上下文的,但是它们被标识为入口点方法。
防火墙允许来自applet的对这些“JCRE入口点对象”的方法的访问(只有JCRE入口点对象的方法是通过防火墙进行访问的,这些对象的域仍然是被防火墙保护的,并且只能通过JCRE上下文进行访问)。入口点的指定允许这些对象的方法可以从任何上下文被调用。当调用发生时,当前上下文将切换到JCRE上下文。
JCRE入口点对象有两种:
1、 临时的JCRE入口点对象
特点:可以从任何一个上下文中被调用。但是,这些对象的引用不能被存储在类的变量、实例变量或数组元素中。但是存储在本地变量(例如方法中定义的局部变量)是允许的。
例子:
APDU对象和所有的JCRE自己的异常对象是临时JCRE入口点对象。比如,APDU对象从applet的process方法参数传进来,applet就可以使用APDU对象的任何方法来服务。
字节码:_putstatic_a、putfield_a_w、_putfield_a_this、_aastore
设置类的静态域,对象的实例变量或数组元素时,防火墙会去检查被存储的引用不是临时JCRE入口点对象。
字节码:_astore、_astore_x等
将一个reference存储到本地变量防火墙不检查。
2、 永久的JCRE入口点对象
特点:可以从任何一个上下文中被调用。但是,这些对象的引用可以被存储。
例子:
JCRE拥有的AID实例是永久的JCRE入口点对象。一个applet可以通过使用JCSystem.getAID()获得自身AID类实例的引用,这个引用是属于JCRE的,然后就可以使用AID实例中的方法。
3、 两者区别
共同特点:
可以从任何一个上下文中被调用。并且只有JCRE本身才能够指定入口点对象并指定它们是临时的还是永久的。
不同点:
临时JCRE入口点对象的引用不能被存储在类的变量、实例变量或数组元素中(本地变量除外)。然后,永久JCRE入口点对象的引用可以被存储。
三、全局数组
只有数组可以被指定为全局的,并且只有JCRE本身可以指定全局数组。所有的全局数组都是临时的全局数组对象。这些对象归JCRE上下文所有,但是可以从任何上下文进行访问。对这些对象的引用不能被存储在类变量、实例变量或数组元素中。但是存储在本地变量(例如方法中定义的局部变量)是允许的。
例子:
APDU缓冲区和applet的install()方法的作为输入参数的字节数组(bArray)。
字节码:_putstatic_a、putfield_a_w、_putfield_a_this、_aastore
设置类的静态域,对象的实例变量或数组元素时,防火墙会去检查被存储的引用不是全局数组。
字节码:_astore、_astore_x等
将一个reference存储到本地变量防火墙不检查。
四、JCRE特权
JCRE上下文是系统上下文,所以它有一些特权。它可以调用卡上的任何对象的方法。JCRE还可以访问卡中任何对象的域和元素,包括属于当前被选定的applet的CLEAR_ON_DESELECT临时对象。
另外,JCRE能够访问A的方法和域,方法的访问是JCRE进入一个applet的上下文的机制(例如JCRE调用应用A的process方法)。
例子:
JCRE调用applet中定义的select、process、deselect、getShareableInterfaceObject等方法。
五、共享接口
共享接口是Javacard API中允许applet间进行交互的一个特性。可共享的接口为内部的applet间的通信提供了一个安全的机制。
一个共享接口定义了一个被共享的接口方法的集合。这些接口方法可以从一个上下文进行调用,即使实现这些方法的对象是属于另一个上下文的applet的。
在javacard API中,一个实现了共享接口的类的实例称之为共享接口对象,简称SIO(Shareable Interface Object)。
重要的是,对于所属的上下文,共享接口对象(SIO)是一个很普通的对象,它的方法和域可以被正常访问,对于任意的其它的上下文,该共享接口对象(SIO)是一个可共享的接口实例,并且只有定义在共享的接口中的方法可以被访问,该共享接口对象(SIO)的其它方法和域是收到防火墙保护,不能随意被访问的。
javacard shareable共享接口实现代码示例如下:
//MyShareable.java
package com.server;
import javacard.framework.Shareable;
import javacard.framework.APDU;
public interface MyShareable extends Shareable{
public abstract void shareMethod(APDU apdu);
}
//ServerApplet.java
package com.server;
import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.AID;
import javacard.framework.Shareable;
public class ServerApplet extends Applet implements MyShareable{
public static void install(byte[] bArray, short bOffset, byte bLength) {
// GP-compliant JavaCard applet registration
new ServerApplet().register(bArray, (short) (bOffset + 1),
bArray[bOffset]);
}
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) 0x00:
break;
default:
// good practice: If you don't know the INStruction, say so:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
//客户端对象通过这个方法来获取共享对象
public Shareable getShareableInterfaceObject(AID serverAID, byte param)
{
return this;
}
public void shareMethod(APDU apdu){
//实现共享方法体
}
//ClientApplet.java
package com.client;
import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.AID;
import javacard.framework.JCSystem;
import javacard.framework.Shareable;
import com.server.*;
public class ClientApplet extends Applet {
private byte[] serverAIDBuffer = {(byte)0xA0, (byte)0x11, (byte)0x22, (byte)0x33, (byte)0x44, (byte)0x55, (byte)0x66};
private AID serverAID = new AID(serverAIDBuffer, (short)0, (byte)serverAIDBuffer.length);;
MyShareable sio;
public static void install(byte[] bArray, short bOffset, byte bLength) {
// GP-compliant JavaCard applet registration
new ClientApplet().register(bArray, (short) (bOffset + 1),
bArray[bOffset]);
}
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) 0x00:
sio = (MyShareable)JCSystem.getAppletShareableInterfaceObject(serverAID, (byte)0);
sio.shareMethod(apdu);
break;
default:
// good practice: If you don't know the INStruction, say so:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
}
转载请注明出处。
END