简体   繁体   中英

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.

Now, assume that I want to send 'Hello' in reception of each APDU command.

What is the difference between these implementations (Memory and CPU consumption)? Which one is best and why?

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

}

Version 1: Buffer stored in EEPROM as an instance variable. This is OK.

Version 2: Buffer stored in EEPROM as a class variable. This is OK.

However, there might be some security issues with static fields as mentioned here https://community.oracle.com/thread/1752580 :

The JCRE creates a context shared by any instance of application that belong to a package. 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)

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.)

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).

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 :

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.

  • Any object owned by the applet instance is referenced from a static field in any package on the card.

Version 3: Each APDU creates a new buffer in EEPROM. A very bad idea. Without the garbage collector your applet will fail very soon because of lack of EEPROM. With the garbage collector your applet will be very slow. Allocate new instances in your applet constructor only or during some initial "Store Data" phase.

Version 4,5: This will not work at all. It will cause exceptions. You cannot store your APDU buffer reference in class or instance variables:

References to the APDU buffer byte array cannot be stored in class variables or instance variables or array components. See Runtime Environment Specification for the Java Card Platform, section 6.2.2 for details.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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