简体   繁体   English

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

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

With regard to absence of the Garbage Collector, I'm confused that what is the best way to define fields and variables? 关于缺少垃圾收集器,我感到困惑的是,定义字段和变量的最佳方法是什么? We know that in Java Card technology those objects that allocated with with new keyword, became unreachable when go out of the scope, but the storage space they occupy will never be reclaimed. 我们知道,在Java Card技术中,使用new关键字分配的那些对象在超出范围时将变得不可访问,但是它们所占用的存储空间将永远不会被回收。

Now, assume that I want to send 'Hello' in reception of each APDU command. 现在,假设我要在接收每个APDU命令时发送“ Hello”。

What is the difference between these implementations (Memory and CPU consumption)? 这些实现之间的区别是什么(内存和CPU消耗)? Which one is best and why? 哪一个最好,为什么?

1- 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- 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- 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- 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- 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);
    }

}

Version 1: Buffer stored in EEPROM as an instance variable. 版本1:缓冲区作为实例变量存储在EEPROM中。 This is OK. 还行吧。

Version 2: Buffer stored in EEPROM as a class variable. 版本2:缓冲区作为类变量存储在EEPROM中。 This is OK. 还行吧。

However, there might be some security issues with static fields as mentioned here https://community.oracle.com/thread/1752580 : 但是,可能存在一些静态字段的安全性问题,如此处https://community.oracle.com/thread/1752580所述

The JCRE creates a context shared by any instance of application that belong to a package. JCRE创建一个上下文,该上下文由属于包的任何应用程序实例共享。 They are separated by the firewall so any application in another context cannot access. 它们被防火墙隔开,因此在其他上下文中的任何应用程序都无法访问。 Static variables and methods don't belong to instance, belong to the class itself so the are out of the scope of the firewall and are accesibles by any application in the smartcard. 静态变量和方法不属于实例,而是属于类本身,因此它们不在防火墙的范围内,并且可由智能卡中的任何应用程序访问。 So we're dealing with a serious security risk. 因此,我们面临着严重的安全风险。

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

Instances of classes—objects—are owned by contexts; 类的实例(对象)由上下文拥有; classes themselves are not. 类本身不是。 There is no runtime context check that can be performed when a class static field is accessed. 访问类静态字段时,无法执行运行时上下文检查。 Neither is there a context switch when a static method is invoked. 调用静态方法时,也没有上下文切换。 (Similarly, invokespecial causes no context switch.) (类似地,invokespecial不会引起上下文切换。)

Public static fields and public static methods are accessible from any context: static methods execute in the same context as their caller. 公共静态字段和公共静态方法可从任何上下文访问:静态方法在与其调用者相同的上下文中执行。

Objects referenced in static fields are just regular objects. 静态字段中引用的对象只是常规对象。 They are owned by whomever created them and standard firewall access rules apply. 它们由创建它们的任何人拥有,并且适用标准防火墙访问规则。 If it is necessary to share them across multiple contexts, then these objects need to be Shareable Interface Objects (SIOs). 如果有必要在多个上下文中共享它们,则这些对象必须是可共享接口对象(SIO)。

The text above does not mean you must not use static fields and methods at all. 上面的文字并不意味着您完全不能使用静态字段和方法。 You just have to consider it carefully. 您只需要仔细考虑。 Another thing is that static references to instances can be dangerous: they can cause a situation, when your applet is impossible to delete as mentioned here: http://askra.de/software/jcdocs/app-notes-2.2.2/garbagecoll.html : 另一件事是,对实例的静态引用可能很危险:当您无法删除您的applet时,它们会引起如下情况: http : //askra.de/software/jcdocs/app-notes-2.2.2/garbagecoll .html

Deleting an applet means that the applet and all of its child objects are deleted. 删除小程序意味着删除该小程序及其所有子对象。 Applet deletion fails if any of the following conditions exist: 如果存在以下任一情况,则删除小程序失败:

  • Any object owned by the applet instance is referenced by an object owned by another applet instance on the card. applet实例拥有的任何对象都被卡上另一个applet实例拥有的对象引用。

  • Any object owned by the applet instance is referenced from a static field in any package on the card. applet实例拥有的任何对象都可以从卡上任何包中的静态字段中引用。

Version 3: Each APDU creates a new buffer in EEPROM. 版本3:每个APDU在EEPROM中创建一个新的缓冲区。 A very bad idea. 一个非常糟糕的主意。 Without the garbage collector your applet will fail very soon because of lack of EEPROM. 如果没有垃圾收集器,由于缺少EEPROM,您的applet将很快失效。 With the garbage collector your applet will be very slow. 使用垃圾收集器,您的applet将非常慢。 Allocate new instances in your applet constructor only or during some initial "Store Data" phase. 仅在applet构造函数中或在某个初始“存储数据”阶段分配新实例。

Version 4,5: This will not work at all. 版本4,5:这根本不起作用。 It will cause exceptions. 它将导致异常。 You cannot store your APDU buffer reference in class or instance variables: 您不能将APDU缓冲区引用存储在类或实例变量中:

References to the APDU buffer byte array cannot be stored in class variables or instance variables or array components. 对APDU缓冲区字节数组的引用不能存储在类变量或实例变量或数组组件中。 See Runtime Environment Specification for the Java Card Platform, section 6.2.2 for details. 有关详细信息,请参见Java Card平台的运行时环境规范,第6.2.2节。

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

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