| By Vijay Phagura, Anita Phagura | Article Rating: |
|
| September 7, 2004 12:00 AM EDT | Reads: |
22,717 |
This article describes a Java Card and how to write applications that can be accessed by enterprise applications. We'll discuss the complete development and testing process for card applications. The sample application and the code listings are kept simple for readability and easier comprehension of the basic ideas.
Java Card
More uses are being found for smart cards since their introduction about a decade ago. As the name suggests, these cards are smarter than the usual magnetic strip cards due to a built-in chip - either a memory chip or a microprocessor. Microprocessor smart cards are becoming more popular as they're more secure and can process information. A Java Card is a smart card with a microprocessor and the smallest Java Virtual Machine (JVM) called the Java Card Virtual Machine (JCVM). Please refer to Sun's specification on Java Card Virtual Machine specs. It makes sense to put a JVM on smart cards due to the following advantages of Java:
- A standard programming language
- Inherent security
- Multiple programs and applet in-stances can coexist on the card due to Java's security
- Integration with mainstream Java IDEs
- Benefits of object-oriented programming
- Platform and vendor independence
The cards with processors usually have an 8-bit microprocessor (similar to 6805 or 8051), although the new cards are coming out with 16-bit processors. They usually contain three types of storage:
- ROM: For persistent, nonvolatile, and nonalterable data
- EEPROM: For persistent, nonvolatile, and alterable data
- RAM: For nonpersistent, volatile, and alterable temporary data
Most Java Cards have a native operating system that interfaces with the JCVM. The Java Card Runtime Environment (JCRE) sits on top of the JCVM and interfaces with the applications (see Figure 1).
The Java Card system supports a small subset of Java APIs that includes the following packages:
- java.lang
- javacard.framework
- javacard.security
- javacardx.crypto
The Java Card java.lang is a subset of the JSDK java.lang. This package provides the basic support for the language, which defines the root class Object and some basic classes for exceptions.
Package javacard.framework
This is an important package for the Java Card; it defines the Applet class and the APDU class, which provides the infrastructure for communication. There are other supporting classes like the PIN class for PIN access and validation support. The Java Card java.lang package does not support the System class so the javacard.framework.JCSystem provides that support.
Package javacard.security
This package provides cryptographic support for the Java Card platform. It's based on the JSDK java.security package.
Package javacardx.crypto
This package provides interfaces and classes that are subject to U.S. export regulations. It's up to the JCRE provider to provide implementations to most of the classes in this package. A smart card may have a separate coprocessor to perform cryptographic operations.
Card Protocol
The card communicates with the host via a card reader in a half-duplex manner. The communication packet is called Application Protocol Data Unit (APDU). The command is sent by the host and the card responds to it. The command APDU is called as C-APDU and response APDU is referred to as R-APDU.
The headers for a C-APDU and R-APDU are shown in Figure 2.
The C-APDU header contains 4 bytes:
- CLA: Class of instruction
- INS: Instruction code
- P1 and P2: Parameters 1 and 2
- Lc: Specifies the length of the data field
- Data field: Data sent to the card
- Le: Number of bytes expected from the card
- Data field: Optional and contains data sent by the card, with the length specified by Le.
- SW1 and SW2: These form the status word. If the value is 0x9000, the communication was successful, otherwise this would represent an exception code.
The JCVM differs from the standard JVM as it's divided into two parts: the interpreter running on the card, and the converter running off-card. The class files are passed through the converter, which produces a converted applet (CAP) file, along with other files. The CAP file is loaded onto the card, which is then instantiated and executed using the interpreter. It's a two-step process to execute a Java Card application.
To download the Java Card Development Kit 2.1.1(JCDK) visit the link in the Resources section. JCDK comes with a reasonably good documentation to get you started.
The Card Applet
The applications developed for cards are Java applets that extend from javacard.framework.Applet, which is one of the differences between a Java Card applet and a regular Java applet. The card applet has a private constructor that can only be instantiated by the JCRE. Also, it has different methods like install, process, etc., unlike the regular applet's init, start, stop, etc., methods. The install method instantiates the applet and the other objects it needs when select is called. The select method prepares the applet to receive APDU commands from the host. The process method processes the APDU commands and prepares responses.
Each package and an applet are identified by an ID called AID. An applet can have an AID 5-11 bytes long. The first 5 bytes of an applet AID should be the same as its package AID.
Java Card Application
We'll now develop an application that will use the Java Card as an identification card for a temporary employee in an organization. The application will be loaded on the card along with his personal information. To retrieve the information that's not stored on the card for this individual (e.g., a start date and an end date of the person's contract, etc.), this application can access the database on the host system. Along with the access function, the card can be used within an organization for various other functions, e.g., an employee is allowed to purchase items from a company store on credit, and the amount due will be stored on this card.
The application designed here supports the following functions:
- Provides an ID for access at the entrance gates
- Allows or disallows entrance to the person by disabling the card. The card can be disabled by at least two conditions:
- Contract expired, detected by off-card application
- Not paying the dues on time, as will be discussed later - Keeps track of amount due
- Keeps track of number of days left to pay the dues
This application demonstrates that all the data for a person does not have to be on the card; a few things can be done by off-card applications on the host system. For instance, the card application does not keep track of when the contract is expiring; this can easily be done off-card. It's extremely important to design the on-card applets carefully in order to respect the resource constraints.
The Code
Listing 1 provides the code for the card applet class EPersonApplet. It seems pretty long at first look, but it is simple. (Listings 1-9 can be downloaded from www.sys-con.com/java/sourcec.cfm.) In brief, the code declares a lot of constants that are instructions for each command that the applet will process and these instructions represent the INS byte of the APDU word. Apart from the INS bytes there's an arbitrary CLA byte for this applet's APDU class and an AID. There are also six fields in this applet to hold the data.
The fields are:
- empId to store the Employee ID
- firstName to store the first name
- lastName to store the last name
- active to indicate whether the card is active
- amount to store the Amount due
- allow to store the number of days to pay the due amount
Next is the constructor. Note that it is declared as private for reasons described earlier. The actual data for each field is described in the comments in this constructor. The constructor takes a byte array as one of the parameters to initialize these fields. The initialization string is 28 bytes. For the sake of this example, each field has been assigned a length, for instance, the name fields can be 10 bytes long and so on. (Note: For testing this applet with the Java Developer Kit 2.1.1, the lengths may have to be reduced because of tool limitations, which takes fewer bytes for initialization.) Some card platforms also send AID + 4 bytes along with the initialization parameters to the applet constructor. These extra 4 bytes are:
- Length of applet instance AID
- Length of application privileges
- Application privileges
- Length of application-specific parameters
One important task for the constructor is to register the instance with the JCRE by calling the register() method of the super class.
The next method is the install(). As soon as the application is installed, the JCRE calls this method, which in turn creates an instance of this applet.
The process() method does all the command processing and in this applet it delegates by calling the appropriate method. This method is also called when the applet is selected by the JCRE. The rest of the code in this method is self-explanatory. It's important to note the exception handling: the class ISO7816 declares constants for the exceptions and the applets can call the throwIt() method on it to throw the exceptions.
The rest of the code implements the commands. The following describes how to send and get data to and from the card. The steps for the "set" commands or sending data to the card applet are:
- Get the APDU buffer reference by using apdu.getBuffer().
- Set the JCRE mode to receive data: let JCRE know the amount of data to receive and receive the data. This all can be done by calling apdu.setIncomingAndReceive() method or by separate methods.
- Check if the number of bytes received is correct.
- Copy the bytes to a local variable.
- Process the received data.
- Get the APDU buffer reference by using apdu.getBuffer().
- Set the JCRE mode to outgoing and let JCRE know the amount of data to send and send the data. This can all be done by calling apdu.setOut-goingAndSend().
- Convert data if necessary.
- Send the data using apdu.setOut-goingAndSend ().
Compile the applet using JSDK 1.3.x, with the Java Card JARs in the classpath, to get a class file.
Using the Java Card Development Kit
Now that we have the applet designed, it's time to test it. Testing can be done off-card for sanity and then loaded to a real card. For testing and simulation we can use the Java Card Development Kit (JCDK) 2.1.1.
The following are brief descriptions of the various tools provided by the JCDK.
Converter
The converter tool in the JCDK converts the class file to a CAP file, which is put on the card. The converter is run on the command line with many options, which are well documented in the JCDK. Another way to run it is to use an .opt file that has all the options defined. Listing 2 provides a sample opt file.
Please refer to the JCDK documentation for the description of all options used in the opt file.
The Converter produces other files too, apart from the CAP file. For now we're only interested in the CAP file. The following line shows how to start the Converter using an opt file.
converter -config egate.opt
JCWDE
This is the Java Card Workstation Development Environment tool that comes with the JCDK. It needs an .app file to run; a sample .app file is shown in Listing 3.
This file lists the applets to be tested. There is an InstallerApplet that always gets loaded before any other applet. More info on this applet can be found in the JCDK documentation. The JCWDE tool can be started on a command line as follows:
JCWDE -p <port #> egate.app
After it has been successfully started it waits to listen on the specified port.
Apdutool
This tool executes the command script, the .scr file, and produces responses from the applet. A sample .scr file is shown in Listing 4. As seen in this listing, the .scr file is a script to run commands. The first few commands are routine commands as there is always an InstallerApplet on the JCDK to install other applets. After these commands the EPersonApplet is selected first before any commands can be issued on it. For more info on the format of the Installer commands, please refer to the JCDK documentation.
This .scr file can be fed to the apdutool, which in turn gives out the responses from the card for each command. Listing 5 shows a sample of these responses. The apdutool can be started as follows:
apdutool egate.scr > egate.out
The output can be sent to a file as shown above or, if the output filename is omitted, the output goes to the console.
As seen from this file, the bytes 0x9000 in the SW1 and SW2 indicate a successful response.
The JCDK is very useful for testing your card applet by simulating it on your workstation. It helps you develop and improve your application without burning up card resources.
These are the steps to test the applet using JCDK tools:
- Write an .opt file to run the Converter tool.
- Convert the class file into a CAP file using the JCDK Converter utility.
- Write an .app file, which describes the applet to the JCWDE. This file lists the installer applet, its AID, and the applet under test and its AID.
- Start the JCWDE tool in a command window using the .app file.
- Write a .scr file, which contains all the APDU commands.
- Run the .scr file through the apdutool in another command window.
Now that we have designed, developed, and unit tested our applet, we're ready to load it onto a real Java Card.
The one we used is called the CyberFlex e-gate 32K card from Axalto. This is one of the cards that supports Java Card 2.1.1. It has 32K of EEPROM space and the hardware specs are as follows:
ROM: 96K RAM: 4K EEPROM: 32K
Enhanced 8-bit CPU with extended addressing modes
Data retention: 10 years
EEPROM endurance: 500,000 write/erase cycles
Single power supply: 2.7V to 5.5V
Icc supply current: MAX 50mA at 5MHz
Axalto also has 64K cards. The 64K card and the 32K e-gate cards are both JavaCard 2.1.1 compliant. The main difference between the 32K and the 64K is the capacity. The 64K card currently does not have an e-gate feature. The final difference is that the 64K card does not have Codeshield (on-card byte code verifier), whereas the Cyberflex 32K e-gate does. There will be an e-gate version of the 64K card available later this year.
Axalto supports all of its cards with an SDK (Software Development Kit), which is very versatile and an all-in-one toolkit. We used the current release - SDK 4.5 version. It's not necessary to use the SDK; however, it includes a set of convenient tools for developing on-card and off-card applications. Specifically, the SDK provides a set of middleware interfaces that makes writing off-card applications very convenient.
For more information on these cards and the features of the SDK please visit the link at the end of this article. The user manual for the SDK is freely downloadable from their site.
Once you have decided on the card, use its software to load the applet onto it. Irrespective of the type of card or toolkit, it's important to note that loading an applet is a multistep process. One important step is to create an instance of an applet. Unlike the JSDK, where class instances are dynamically created, in the card it's not dynamic anymore. You have to create an instance manually before using the application through a toolkit. Before sending APDU commands to the applet on the card, the applet has to be selected. The selecting process can be done through a tool provided by the vendor or via an APDU command.
The applet can be tested using the card's toolkit. We used an Axalto SDK tool called APDU Manager to test the applet. You can send APDU commands from the tool to the card and also see the logs of responses sent by the card.
Off-Card Application
Now that we have tested our applet on an actual card, let's focus on the off-card application. The off-card application or host application will access the card applet or may be part of another larger application on the host.
These applications can be written using the Open Card Framework (OCF), details of which can be found at the link given at the end of this article. The CyberFlex e-gate cards support this framework, but the functionality achieved is limited. To write this application we used Axalto's middleware libraries, which come with their SDK.
As mentioned earlier, this application can be part of a bigger enterprise application. This can be hooked as a proxy to the actual card and act as an API to the card applet. For this reason we named this application CardProxy. The CardProxy acts as a card listener to capture asynchronous events like card insertion, card removal, etc.
Listing 6 shows the complete code for the CardProxy class. The code has been kept simple, omitting thread safety and some error-handling scenarios.
Similar to the EPersonApplet, there are a few constants for the commands. Apart from that there are byte arrays that define the applet AID and the keys for the card. The keys are needed to establish a secure channel with the card before the applet is selected.
As seen in the code, the CardProxy class has to interface with JNI and hence loads the library in the static intializer. It also has to create an IOP object, static in this case, that represents the interoperable layer. The other important thing to note is the connect() method. In this method a connect() is called on the IOP object. Even if this call returns true, the system needs some time before the EstablishSecureChannel method is invoked. After a secure channel has been successfully established, the applet needs to be selected. After this is successfully accomplished, only then can we "connect" to the card. In case of an error, the error is acquired from the card by invoking the method getErrorMessage(). The connect() on the CardProxy is called from two places: the constructor and the CardInserted() callback. The constructor call to connect() is useful if the card is already inserted before starting the host application.
Most of this class contains getters and setters that use the method SendCardAPDU() on the SmartCard object. This method takes six parameters: command class code, instruction code, p1, p2, a zero length int array, and the length of the output data. The data is returned in a short array, each element of which contains a byte of info. The 0th element contains the MSB and the nth element contains the LSB. The SendCardAPDU() is also used to set data onto the card. It's used exactly as described earlier except the zero length int array now contains the data to be set.
The command getAllInfo() is slightly different; it extracts all the info from the card and creates an Employee object. Listing 7 shows a partial code for Employee class. It's a simple class with accessors and mutators for the employee data.
The Client
The real host application to use all of the functionality of the CardProxy class is the Viewer class. Listing 8 shows a simple version of the Viewer that accesses all the commands of the card.
A client application can be as simple as the Viewer listed above or an RMI component with a JDBC object to access the database, and it communicates with an application server-deployed application. The basic idea for accessing a Java Card is the same. Listing 9 provides another version of the Viewer class, which is a stand-alone Swing applet.
Conclusion
Although Java Card technology is not that new, it's still unexplored territory for many. It is advancing fast and today there are more applications for it. We have tried to describe the full development process of a small project. We hope this article was motivating and provided some practical insight into Java Card application development.
Acknowledgments
We thank Axalto and, especially, David Teo and his team for providing excellent support and hardware, without which it would have been difficult to write this article.
Resources
Published September 7, 2004 Reads 22,717
Copyright © 2004 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Vijay Phagura
Vijay Phagura, a professional Java/J2EE consultant has over twelve years of experience in software architecture and development. Vijay currently consults with companies; he specializes in architecture and development of software using J2EE and other Java technologies, like JDMK.
More Stories By Anita Phagura
Anita Phagura has more than 12 years of experience in software development. She has designed and worked with many different Java and J2EE technologies and APIs. She also has experience with different GUI technologies. Anita has patent pending for some of her work in the software architecture and design arena.
![]() |
Prakashkumar 06/27/07 10:49:07 PM EDT | |||
Hi, |
||||
- Kindle 2 vs Nook
- Why IBM’s Server Chief Got Busted
- Is Cloud Computing Like Teenage Sex?
- Industry Experts Discuss the State of Cloud Computing
- Performance Tuning Essentials for Java
- Confessions of a Ulitzer Addict
- Tactical Cloud Computing Panel at 1st Annual GovIT Expo
- It's the Java vs. C++ Shootout Revisited!
- Cloud Computing Can Revitalize Your Career as Software Developer
- IBM Could "Reinvent" Java: Mills
- Oracle & Cloud Computing: Exclusive Q&A with SVP Richard Sarwal
- A Brief History of Cloud Computing
- Kindle 2 vs Nook
- Cloud CEOs, CTOs & SVPs to Speak at 4th International Cloud Computing Expo
- Why IBM’s Server Chief Got Busted
- Is Cloud Computing Like Teenage Sex?
- Industry Experts Discuss the State of Cloud Computing
- Performance Tuning Essentials for Java
- The Difference Between Web Hosting and Cloud Computing
- Cloud Computing Expo: Exclusive Q&A with Yahoo! SVP Cloud Computing
- Ajax in RichFaces 3.3, JSF 2 and RichFaces 4
- Confessions of a Ulitzer Addict
- My Thoughts on Ulitzer
- Tactical Cloud Computing Panel at 1st Annual GovIT Expo
- A Cup of AJAX? Nay, Just Regular Java Please
- Java Developer's Journal Exclusive: 2006 "JDJ Editors' Choice" Awards
- The i-Technology Right Stuff
- JavaServer Faces (JSF) vs Struts
- Rich Internet Applications with Adobe Flex 2 and Java
- Java vs C++ "Shootout" Revisited
- Bean-Managed Persistence Using a Proxy List
- Reporting Made Easy with JasperReports and Hibernate
- Creating a Pet Store Application with JavaServer Faces, Spring, and Hibernate
- What's New in Eclipse?
- Why Do 'Cool Kids' Choose Ruby or PHP to Build Websites Instead of Java?
- i-Technology Predictions for 2007: Where's It All Headed?





































