繁体   English   中英

编写Java卡小程序的有效方法是什么?

[英]What is the efficient way in writing a java card applet?

关于缺少垃圾收集器,我感到困惑的是,定义字段和变量的最佳方法是什么? 我们知道,在Java Card技术中,使用new关键字分配的那些对象在超出范围时将变得不可访问,但是它们所占用的存储空间将永远不会被回收。

现在,假设我要在接收每个APDU命令时发送“ Hello”。

这些实现之间的区别是什么(内存和CPU消耗)? 哪一个最好,为什么?

1-

public class SimpleApp extends Applet {
    byte[] hello = { (byte) 'H', (byte) 'e', (byte) 'l', (byte) 'l', (byte) 'o' };;

    private SimpleApp() {
    }

    public static void install(byte bArray[], short bOffset, byte bLength)
            throws ISOException {
        new SimpleApp().register();
    }

    public void process(APDU arg0) throws ISOException {
        byte[] buffer = arg0.getBuffer();
        Util.arrayCopyNonAtomic(hello, (short) 0, buffer, (short) 0, (short) 5);
        arg0.setOutgoingAndSend((short) 0, (short) 5);
    }
    }

2-

public class SimpleApp extends Applet {
    static byte[] hello = { (byte) 'H', (byte) 'e', (byte) 'l', (byte) 'l', (byte) 'o' };;

    private SimpleApp() {
    }

    public static void install(byte bArray[], short bOffset, byte bLength)
            throws ISOException {
        new SimpleApp().register();
    }

    public void process(APDU arg0) throws ISOException {
        byte[] buffer = arg0.getBuffer();
        Util.arrayCopyNonAtomic(hello, (short) 0, buffer, (short) 0, (short) 5);
        arg0.setOutgoingAndSend((short) 0, (short) 5);
    }

}

3-

public class SimpleApp extends Applet {
    byte[] hello = { (byte) 'H', (byte) 'e', (byte) 'l', (byte) 'l', (byte) 'o' };;

    private SimpleApp() {
    }

    public static void install(byte bArray[], short bOffset, byte bLength)
            throws ISOException {
        new SimpleApp().register();
    }

    public void process(APDU arg0) throws ISOException {
        byte[] buffer = new byte[255];
        buffer = arg0.getBuffer();
        Util.arrayCopyNonAtomic(hello, (short) 0, buffer, (short) 0, (short) 5);
        arg0.setOutgoingAndSend((short) 0, (short) 5);
    }

}

4-

public class SimpleApp extends Applet {
    static byte[] hello = { (byte) 'H', (byte) 'e', (byte) 'l', (byte) 'l', (byte) 'o' };;
    byte[] buffer;
    private SimpleApp() {
    }

    public static void install(byte bArray[], short bOffset, byte bLength)
            throws ISOException {
        new SimpleApp().register();
    }

    public void process(APDU arg0) throws ISOException {
        buffer = arg0.getBuffer();
        Util.arrayCopyNonAtomic(hello, (short) 0, buffer, (short) 0, (short) 5);
        arg0.setOutgoingAndSend((short) 0, (short) 5);
    }

}

5-

public class SimpleApp extends Applet {
    static byte[] hello = { (byte) 'H', (byte) 'e', (byte) 'l', (byte) 'l', (byte) 'o' };;
    static byte[] buffer;
    private SimpleApp() {
    }

    public static void install(byte bArray[], short bOffset, byte bLength)
            throws ISOException {
        new SimpleApp().register();
    }

    public void process(APDU arg0) throws ISOException {
        buffer = arg0.getBuffer();
        Util.arrayCopyNonAtomic(hello, (short) 0, buffer, (short) 0, (short) 5);
        arg0.setOutgoingAndSend((short) 0, (short) 5);
    }

}

版本1:缓冲区作为实例变量存储在EEPROM中。 还行吧。

版本2:缓冲区作为类变量存储在EEPROM中。 还行吧。

但是,可能存在一些静态字段的安全性问题,如此处https://community.oracle.com/thread/1752580所述

JCRE创建一个上下文,该上下文由属于包的任何应用程序实例共享。 它们被防火墙隔开,因此在其他上下文中的任何应用程序都无法访问。 静态变量和方法不属于实例,而是属于类本身,因此它们不在防火墙的范围内,并且可由智能卡中的任何应用程序访问。 因此,我们面临着严重的安全风险。

或此处: http : //pfa12.free.fr/doc_java/javacard_specifications/specs/jcre/html/JCRESpec06firewall.html (第6.1.6章)

类的实例(对象)由上下文拥有; 类本身不是。 访问类静态字段时,无法执行运行时上下文检查。 调用静态方法时,也没有上下文切换。 (类似地,invokespecial不会引起上下文切换。)

公共静态字段和公共静态方法可从任何上下文访问:静态方法在与其调用者相同的上下文中执行。

静态字段中引用的对象只是常规对象。 它们由创建它们的任何人拥有,并且适用标准防火墙访问规则。 如果有必要在多个上下文中共享它们,则这些对象必须是可共享接口对象(SIO)。

上面的文字并不意味着您完全不能使用静态字段和方法。 您只需要仔细考虑。 另一件事是,对实例的静态引用可能很危险:当您无法删除您的applet时,它们会引起如下情况: http : //askra.de/software/jcdocs/app-notes-2.2.2/garbagecoll .html

删除小程序意味着删除该小程序及其所有子对象。 如果存在以下任一情况,则删除小程序失败:

  • applet实例拥有的任何对象都被卡上另一个applet实例拥有的对象引用。

  • applet实例拥有的任何对象都可以从卡上任何包中的静态字段中引用。

版本3:每个APDU在EEPROM中创建一个新的缓冲区。 一个非常糟糕的主意。 如果没有垃圾收集器,由于缺少EEPROM,您的applet将很快失效。 使用垃圾收集器,您的applet将非常慢。 仅在applet构造函数中或在某个初始“存储数据”阶段分配新实例。

版本4,5:这根本不起作用。 它将导致异常。 您不能将APDU缓冲区引用存储在类或实例变量中:

对APDU缓冲区字节数组的引用不能存储在类变量或实例变量或数组组件中。 有关详细信息,请参见Java Card平台的运行时环境规范,第6.2.2节。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM