As promised, in this conclusion to our two-part article, we will run an applet in a Java Card Simulator. This document contains only the setup and methods to run the Java Card applet in the simulator jcwde. The apdutool will act as the host application for sending command APDU.
You can download the Java
Card 2.1.1 Development Kit here (Please begin with Version 2.1.1 and move on to 2.1.2.).
Unzip the Windows .zip file that you have downloaded as a self-created directory, jc211.
Set up these environment variables.
You can create a separate jc211env.bat file so that you just have to run that batch file. The batch file can be created like this:
Important: Open two windows one after another and set the paths in each window. These windows will work for simulating the Java Card environment and the host application.
Steps to run the applet in Java Card:
- Compile the class.
- Use Converter to produce CAP, EXP, and JCA files. Converter is an off-card VM that checks whether your applet is using a correct subset of the Java language and loads the classes of the package.
- Then you run simulator JCWDE that simulates the applet as if it were running in the ROM of a card. It emulates the card environment. The Simulator takes the jcwde.app file that tells you where and what applet needs to mask.
- Run the apdutool, which takes a script file (having command APDUs) and sends to JCWDE (simulator) where the C-APDU processed by your applet is, and the result is sent by JCWDE back to the apdutool.
Reminder: make sure which drive you have installed the Java Card package on, which should be in directory jc211 — lets assume it’s in C Drive (c:jc211).
The settings on my computer are:
C:jdk1.3 -- Java Virtual Machine C:jc211 -- Java Card C:wallet -- package to be masked in Java Card D:javac -g -classpath c:jc211binapi21.jar c:walletWallet.java
This will create the Wallet.class file(s).
The Converter tool comes with jc211 used as an off-card verifier. The Converter loads and processes the class files that make up the package. The Converter outputs three files CAP, EXP, and JCA. The CAP file — for Converted Applet — is used to mask the applet in the smart card. The EXP — for export — file gives the Public linking information with other methods and classes. And the JCA — for Java Card Assembly — file is a human-readable ASCII file for testing and debugging The JCA file can be given to capgen to produce the CAP file.
Note here that I am executing the converter command from the root — C: .
c:converter -config c:walletWallet.opt where c:walletWallet.opt file content is: -out EXP JCA CAP //telling the converter to output three files -exportpath d:jc211api21 // giving the converter information to look for exp file to link -applet 0xa0:0x0:0x0:0x0:0x62:0x3:0x1:0xc:0x6:0x1 wallet.Wallet //applet name and AID wallet 0xa0:0x0:0x0:0x0:0x62:0x3:0x1:0xC:0x6 1.0 //package name and AID
JCWDE is a simulator that provides the runtime environment for the Java Card. We need to create a file, jcwde.app, that needs to be passed to the Simulator.
The jcwde.app file will look like this:
//applet AID com.sun.javacard.installer.InstallerApplet 0xa0:0x0:0x0:0x0:0x62:0x3:0x1:0x8:0x1 wallet.Wallet 0xa0:0x0:0x0:0x0:0x62:0x3:0x1:0xc:0x6:0x1
The file jcwde.app is in my computer placed at the root, which in my case is C:jcwde.app.
In one window, type:
D:>jcwde -p 9025 jcwde.app
9025 is the default port where the Simulator is listening to receive the C-APDU from the apdutool.
Edit the input.scr file to include these commands:
powerup; // Select the installer applet 0x00 0xA4 0x04 0x00 0x09 0xa0 0x00 0x00 0x00 0x62 0x03 0x01 0x08 0x01 0x7F; // 90 00 = SW_NO_ERROR // begin installer command 0x80 0xB0 0x00 0x00 0x00 0x7F; // create wallet applet 0x80 0xB8 0x00 0x00 0x11 0x0a 0xa0 0x0 0x0 0x0 0x62 0x3 0x1 0xc 0x6 0x1 0x05 0x01 0x02 0x03 0x04 0x05 0x7F; // end installer command 0x80 0xBA 0x00 0x00 0x00 0x7F; ///////////////////////////////////////////////////////////////////// // Initialize Wallet ///////////////////////////////////////////////////////////////////// //Select Wallet 0x00 0xA4 0x04 0x00 0x0a 0xa0 0x0 0x0 0x0 0x62 0x3 0x1 0xc 0x6 0x1 0x7F; // 90 00 = SW_NO_ERROR //Verify user pin 0xB0 0x20 0x00 0x00 0x05 0x01 0x02 0x03 0x04 0x05 0x7F; //90 00 = SW_NO_ERROR //Get wallet balance 0xB0 0x50 0x00 0x00 0x00 0x02; //0x00 0x00 0x00 0x00 0x90 0x00 = Balance = 0 and SW_ON_ERROR //Attemp to debit from an empty account 0xB0 0x40 0x00 0x00 0x01 0x64 0x7F; //0x6A85 = SW_NEGATIVE_BALANCE //Credit $100 to the empty account 0xB0 0x30 0x00 0x00 0x01 0x64 0x7F; //0x9000 = SW_NO_ERROR //Get Balance 0xB0 0x50 0x00 0x00 0x00 0x02; //0x00 0x64 0x9000 = Balance = 100 and SW_NO_ERROR //Debit $50 from the account 0xB0 0x40 0x00 0x00 0x01 0x32 0x7F; //0x9000 = SW_NO_ERROR //Get Balance 0xB0 0x50 0x00 0x00 0x00 0x02; //0x00 0x32 0x9000 = Balance = 50 and SW_NO_ERROR //Credit $128 to the account 0xB0 0x30 0x00 0x00 0x01 0x80 0x7F; //0x6A83 = SW_INVALID_TRANSACTION_AMOUNT //Get Balance 0xB0 0x50 0x00 0x00 0x00 0x02; //0x00 0x32 0x9000 = Balance = 50 and SW_NO_ERROR //Debit $51 from the account 0xB0 0x40 0x00 0x00 0x01 0x33 0x7F; //0x6A85 = SW_NEGATIVE_BALANC //Get Balance 0xB0 0x50 0x00 0x00 0x00 0x02; //0x00 0x32 0x9000 = Balance = 50 and SW_NO_ERROR //Debit $128 from the account 0xB0 0x40 0x00 0x00 0x01 0x80 0x7F; //0x6A83 = SW_INVALID_TRANSACTION_AMOUNT //Get Balance 0xB0 0x50 0x00 0x00 0x00 0x02; //0x00 0x32 0x9000 = Balance = 50 and SW_NO_ERROR //Reselect Wallet applet so that userpin is reset 0x00 0xA4 0x04 0x00 0x0a 0xa0 0x0 0x0 0x0 0x62 0x3 0x1 0xc 0x6 0x1 0x7F; // 90 00 = SW_NO_ERROR //Credit $127 to the account before pin verification 0xB0 0x30 0x00 0x00 0x01 0x7F 0x7F; //0x6301 = SW_PIN_VERIFICATION_REQUIRED //Verify User pin with wrong pin value 0xB0 0x20 0x00 0x00 0x04 0x01 0x03 0x02 0x66 0x7F; //0x6300 = SW_VERIFICATION_FAILED //Verify user pin again with correct pin value //0xB0 0x20 0x00 0x00 0x08 0xF2 0x34 0x12 0x34 0x56 0x10 0x01 0x01 0x7F; 0xB0 0x20 0x00 0x00 0x05 0x01 0x02 0x03 0x04 0x05 0x7F; //0x9000 = SW_NO_ERROR //Get balance with incorrrect LE value 0xB0 0x50 0x00 0x00 0x00 0x01; //0x6700 = ISO7816.SW_WRONG_LENGTH //Get balance 0xB0 0x50 0x00 0x00 0x00 0x02; //0x00 0x32 0x9000 = Balance = 50 and SW_NO_ERROR // *** SCRIPT END *** powerdown;
In another window, type:
D:>apdutool input.scr > input.out.scr
In this presentation, I’ve introduced smart cards and how to use Java Card Technology to leverage smart cards. I’ve also told you about the framework of the Java Card applet. After that, I’ve offered you some explanation as to how to write command and response APDU. Because the communication interface between the card and CAD is APDU, I’ve told you how each pair of command and response APDU headers are constructed. Then I gave you the basic setup and running instructions to run the JCWDE (the Simulator of the Java Card on which your applet is running as if its masked in the ROM of the smart card) and apdutool (which acts as an application or CAD to transmit your command APDU and receive an executed result in the form of response APDU.
Key Words To Remember:
JCRE — Java Card Runtime Environment
CAD — Card Application Device
AID — Application Identifier
APDU — Application Protocol Data Unit
Masked — Burning an applet in the ROM of a Smart Card
Wallet.java comes with Sun Java Card examples in the Java Card package, courtesy of Sun Microsystems.
About the Author
Arsalan K. Lodhi is finishing his second bachelor’s degree in computer science, with emphasis in distributed computing, at Cal State Long Beach. He is a Sun Certified Java Programmer.