How to utilize Java in your wallet or purse
This month’s Java Developer column, the third in a series on smart cards, will start by describing the CyberFlex card from Schlumberger. We will then write a program for this card, convert it to “card format,” download it, and run it. We will briefly discuss a security application and go on to discuss personalization — the process of making a card specific to its holder. We will also provide techniques for programming smart cards and ensuring security. Smart card security can be a very large topic as security is one of the key features of smart cards. As a start, we will demonstrate a technique for carrying out what is commonly referred to as card holder verification. The article ends with a frequently-asked-questions (FAQ) section.
Note: For the big picture on the Java Card API, please see the companion piece to this article: “Giving currency to the Java Card API,” by Arthur Coleman.
In order to benefit from the concepts in this article, you must have Schlumberger’s CyberFlex developer kit. (See the Resources section for information on what to do if you really want to run the demos without changing a line of code.) Some of the examples included here can be modified for other cards that may come to market as time goes on. The resources at the end of the article provide information on other cards coming soon from Bull and GemPlus.
What is the CyberFlex Java Card?
In previous articles in this series (see “Smart cards: A primer” and “Smart cards and the OpenCard Framework,” we discussed how to use Java to communicate with a smart card and how to develop a smart card terminal interface. CyberFlex is a smart card from Schlumberger that runs programs written in the Java programming language. The CyberFlex card looks almost exactly like a credit card but is in fact a small computer. The card contains a microprocessor to provide processing capability and memory for storing instructions and data. For more on CyberFlex 2.0 and its relation to Java Cards, see the Frequently asked questions section. The card can be broken down into the following functional areas:
- CPU
- RAM
- ROM
- EEPROM
The card can be used to store and update account information, personal data, and even monetary value. The cards are ideal for secure Internet access, purchases, portable digital telephones, and for benefit programs and healthcare applications. Smart cards bring new services, as well as increased security, portability, and convenience, to computer applications. The following diagram depicts an architecture capable of supporting multiple applications.
Some consumers have expressed extreme concern with the idea of having their health information and their banking information in the same place and then interacting with some online service. Smart card manufacturers have been working on this problem for years and have come up with security based on partitioning.
Simple example
The example we will start with is very simple. As we have discussed in previous articles, the ATR (“answer to reset”) is fundamental to ISO 7816 — the recognized standard for communicating with smart cards. ATRs are the means by which a card provides some identifying information when the card is reset or inserted in a reader. The ATR is well-defined in the ISO standards. The recent OpenCard article published last month in JavaWorld included an excellent ATR-dumping facility that we will use this month.
Our first example is a cardlet (the name of a collection of Java classes that run on a card) that modifies the ATR to respond with some specific information. The application will be downloaded to the card and installed as the start-up program. When the card is reset, the ATR that is sent from the card to the application via the smart card reader is the ATR from our application. The steps we need to perform are:
- Write the application
- Post process the java .class files for the CyberFlex card
- Download the application using the development tools
- Test the application
The application “CardHello”
The application we are writing appears below. We are using a generic ATR and setting the string “Hello World” into the ATR field. The ATR is fully described in ISO 7816-3. The code for this program follows, and it is commented for you in great detail. (Notice the different requirements for 2.0 and pre-release cards)
/*
* CardHello: Custom ATR
*/
// Use import for CyberFlex 2.0 only; Comment out for pre-release cards
// import javacardx.framework.*;
public class CardHello {
public static void main() {
/////////////////////////////////////////
// Without this statement, you could potentially
// lock a card out forever. This statement allows the
// default system loader to be executed on the
// next reset. In other words, without this
// statement, the CyberFlex card will run
// your downloaded program every time, so if it has
// a bug you will be unable to get to it --
// unless, of course, your program has the ability to
// unload itself and restore the default loader.
/////////////////////////////////////////
_OS.Execute((short)0,(byte)0); // Return control to default loader
byte ATR[] = new byte[4];
ATR[0] = 0x3B;
////////////////////////////////////////////
// Send the first byte of the ATR to gain some time.
// Welcome to the world of real time. Some readers
// require responses within x ms of inserting a card,
// so we send one byte to the reader to get it to wait,
// and then send the rest of the data.
////////////////////////////////////////////
_OS.SendMessage(ATR,(byte)1);
////////////////////////////////////////////
// Fill the last part of the ATR and send it
// starting at ATR[4]. The prior bytes are ATR
// data and can be decoded using the ISO 7816
// specification. Unfortunately, ISO charges
// you for a copy of the specification.
////////////////////////////////////////////
ATR[0] = (0x30 | 0x0a);
ATR[1] = 0x15;
ATR[2] = 0x00;
ATR[3] = 0x49;
_OS.SendMessage(ATR,(byte)4);
//////////////////////////////
// Write the historical data
//////////////////////////////
byte atrHistorical[] = new byte[10];
atrHistorical[0] = 'H';
atrHistorical[1] = 'e';
atrHistorical[2] = 'l';
atrHistorical[3] = 'l';
atrHistorical[4] = 'o';
atrHistorical[5] = 'W';
atrHistorical[6] = 'o';
atrHistorical[7] = 'r';
atrHistorical[8] = 'l';
atrHistorical[9] = 'd';
_OS.SendMessage(atrHistorical,(byte) atrHistorical.length);
//////////////////////////////
// Wait here forever
//////////////////////////////
while (true) ;
}
}
Post processing: Converting the class bytes to a format understood by the card
The Resources section contains all of the code required for this example. You should be able to compile the above program. Make sure you have the OS.class
file in your directory. This file provides some of the card-specific methods for the Card Operating System. This post-processing step is necessary to convert the card bytes to a format understood by the card. It will be awhile before Java Cards can understand .class bytes directly. By running the command mksolo.exe
, you should get something like this:
Schlumberger (R) (a registered trademark) MakeSolo (a trademark) Post-processor
Version 1.001 Copyright (C) Schlumberger Technologies 1997. All rights
reserved.
Solo size statistics:
Output: 238 bytes; Max stack: 8 bytes; Max object: 0 bytes
Successfully generated cardlet 'CardHello.bin'
Downloading the application
Here is a brief walkthrough of how to get started downloading a Java program to a CyberFlex card using EZ Formatter with a Litronic 210 reader. EZ Formatter is a Windows 95 utility program for loading applications to the Cyberflex card. The Litronic 210 is a smart card reader distributed with the Schlumberger development kit. See the Resources section for more information on these tools.
-
Test your smart-card reader connection. For the Litronic reader, there is a test program that blinks the green LED 10 times. This will ensure that there is no hardware problem or software conflict. To use this program, run
..SchlumbergerCyberFlex SDKLitronicConfig
, select the port that the reader is connected to, and press the “Test” button. If everything is okay, the green LED on the reader will blink 10 times. Press “OK” to exit this program. -
From the Windows Explorer, select “Ez2us” in the “EZ Formatter” directory, and select “Properties” from the “File” menu. At the time of this writing, the correct created date is 5/13/97 5:35 PM.
-
Run EZ Formatter (“Ez2us” in the “EZ Formatter” directory).
-
A “System Configuration” window should come up. (If it doesn’t, select the “System Configuration” button on the toolbar, just left of the monitor and “?” icons.)
-
Select LITR210.RDC for the reader file.
-
Select CYBERFLX.CDC for the card file.
-
Select your port (probably Com1, but depends on your reader connection).
-
Select “OK.”
-
Insert a CyberFlex card into the reader.
-
Press the “Power On” button on the toolbar (the left-most button). The green LED on your Litronic reader will illuminate. You should see a message at the bottom that the card and reader are ready. At the top, you should see an ATR string, ATR = 3B 32 15 00 49 10.
Note: If you see an error here, it may be that the selected COM port, that is COM1, is being used by some other system process, such as PC/SC, which defaults to using COM1. If you have multiple COM ports on your machine, you can simply redirect EZ Formatter to use a different COM port. If you have a single COM port, you will have to disable PC/SC (or any other process using that COM port) so that EZ Formatter can use the COM port.
-
Select the box to the right of the “?” icon on the tool bar. Enter 2222. (This is the File ID of the Java program, as initialized on your CyberFlex card.)
-
Press the arrow button just to the right of this box. You should see a message at the bottom: File/Directory “22 22” Now Active.
-
Press the LoadSolo (CyberFlex) tab. It should show File ID 2222.
-
Press the “Get Java Program” button. Select your .BIN file as generated by MakeSolo. The program will load and display in the larger window. Make sure that the last bytes of your program are “4D 00 00 00”. (All CyberFlex programs must end with this sequence.)
-
Select the “Download” button. Press “YES” on the confirmation dialog.
-
A “Security Manager” dialog will now appear. Select Key 0 on the list on the left side. Select Hex Values for the Code/Key Format. The box at the lower right side should now be labeled “Present Key 0”. Enter “AD 9F 61 FE FA 20 CE 63” in this box, and press the “Present” button.
-
A message should appear at the bottom: Key/Code approved. If so, press the “Close” button. If not, check your key and re-enter.
-
After pressing the “Close” button, you should see the download proceeding one line at a time in the lower window. Do not press any key or button until this download completes. The download should end with “4D 00 00 00t”. The message at the bottom should say “OK”.
- Press the “Set To Run” button. This will cause your Java program to execute on the next reset. Your program must contain the statement:
_OS.Execute((short)0, (byte)0);
. This should preferably be the first line in your program, to make sure that the statement executes regardless of any other bug in your program. If you set a program to run that does not execute this statement, your card will never be able to download or run any other program, ever. This is irreversible!
Running and testing your application
You are now ready to run your Java program. On the next reset, your program will run. You should see the ATR specified in the example above; in EZFormatter ATR displays in the upper righthand corner of the screen. Assuming your program executes the _OS.Execute
command as above, the next reset after your program runs will put you back in the default loader program, where you can repeat this process to download changes to your program.
If you just wish to execute the same program a second time, you can select file 2222, select the Security Manager (the Lock icon on toolbar), enter your Key/Code in the Security Manager, and set program 2222 to run again, bypassing the “Get Java Program” and “Download” steps.
After becoming comfortable with these steps, I suggest exploring the EZ Formatter documentation to learn how to better use this program for your needs.
Running this example with OpenCard
Security
There are many security approaches with cards. One popular technique is to start with the following tenet: Everything on the card is secure because it was put there via a secure methodology, and the card is tamper-resistant. In other words, everything in the house is safe because you put it in there (except, of course, for that Trojan horse — the unsafe products that you thought were safe), and you have a key to your house. Smart cards are tamper resistant — so good security designs don’t allow unauthorized modification or tampering. In order to allow data and/or objects to be moved to and from cards, access control lists can be used to provide controlled access. We saw this in our downloading process in which we were required to enter a key in order to update a file.
Smart cards are often organized as files, so by setting the abilities associated with a file and the associated key, one can realize finer grained security (like read, write, and so on). For example your key may only read while mine allows read and write of the same file. In order to grant the ability initially, you will need a key, or set an ability granting key. I hope it is obvious that if you do not restrict who can set the security policy, you will have no security.
Here is a small example that demonstrates how to perform card holder verification. Card holder verification is the most important process to get right. There are many techniques and very explicit requirements in this area (see Resources). For example, with OpenCard we saw that banks often require that the PIN never enter or leave the “trusted environment” around a card. (Security people often define an area of trust when analyzing a security solution; in this case, the environment is the card, the card reader, the connection to the computer, and the PIN entry.) Secure PIN entry often is accomplished by using a card reader that has a PIN pad directly attached to the reader so that the PIN never leaves the reader environment. Our example below does not use this technique because the reader does not have a PIN pad.
import Java Cardx.framework.*;
public class Verifchv {
// Constants used throughout the program
static final byte ACK_CODE = (byte)0;
static final byte BUFFER_LENGTH = 32;
static final byte ISO_COMMAND_LENGTH = (byte)5;
public static void main () {
// Reset the RST bootstrap pointer to the ROM bootstrap
_OS.Execute((short)0, (byte)0);
byte bReturnStatus;
byte pbuffer[] = new byte[ISO_COMMAND_LENGTH];
byte dbuffer[] = new byte[BUFFER_LENGTH];
/////////////////////////////////////////////////////////
// Look for a message that contains the correct key
/////////////////////////////////////////////////////////
while (true) {
// Command w/ right chv is
// pBuffer = C0 20 00 01 08
// dBuffer = 48 49 4A 4B 4C 4D 4E 4F
_OS.GetMessage(pbuffer, ISO_COMMAND_LENGTH, ACK_CODE);
bReturnStatus = _OS.VerifyCHV(pbuffer[3], dbuffer, (byte)0x00);
_OS.SendStatus((byte)bReturnStatus);
/////////////////////////////////////////////////////////
// Give the user access and/or data based on success
// or failure of the CHV
/////////////////////////////////////////////////////////
}
}
}
Card personalization principles
Personalization consists of creating a file architecture adapted to your specific needs. The files you can create are program or data files organized into directories and sub-directories. On CyberFlex 2.0 3K, the storage is very limited. CyberFlex 1.0 introduced a default file system. Now CyberFlex 2.0 enables you to create your own; it is up to you to optimize it according to your specific needs.
Program file
You have to create a file big enough to fit your program. When developing, look at the statistics generated by MakeSolo and be sure the space is large enough (add a reasonable safety margin for tune-up).
CHV files
The CHV files are specific files that need to be created if one wants to use the CHV methods. The CHV files have very strict requirements as far as name and structure are concerned. Both CHV files should be located in the root directory. For CHV1, the ID should be 0000; for CHV2, the ID should be 0100.
For additional information, look in the CHV section in the manual for more information, or use the example discussed later in this article.
Changing the structure to file system layout
You will probably not be able to create the correct architecture right from the beginning, so you need to be able to recreate the right one. In CyberFlex 2.0, you can only delete the last created file in the directory, so it is a good idea to keep track of the order of file creation. You can also use the Directory APDU from the CyberFlex loader to scroll through the files in a directory and get a clear definition of the file structure.
Example: Creating CyberFlex 1.0 default file architecture in a 2.0 card
The operations to perform for the CyberFlex 1.0 file architecture follow:
- Verify Key 0 (to get enough privileges to create files)
- Create the CHV1 (id=0000) file using command APDU CreateFile from the CyberFlex Loader
- Create the Program File (ID=2222)
- Create the data directory (ID=7777)
- Select the data directory 7777
- Create the first binary data file (ID=7701)
- Create the second binary data file (ID=7702)
- Create the record file (ID=7703)
To delete the structure, just delete the files in the reverse order in which you created them.
- Reset the card
- Verify key0
- Select directory 7777
- Delete file 7703
- Delete file 7702
- Delete file 7701
- SelectParent
- Delete data directory 7777
- Delete the program file 2222
- Delete the CHV file 0000
Be careful not to delete the file 0011 (key file) as the default Access Control lists on the main directory require that Key 0 is verified to create or delete a file. If you delete the key file, it will be impossible to create the file again and your card will be useless.
Security
Earlier we mentioned CHV and personalization. CHV is a start and pretty easy to understand. One of the most valuable aspects of smart cards is the security they offer. As shown in the example above, keys are required to download and store programs, and there are facilities for performing a card holder verification. Next month we will expand on this and discuss security more broadly. Specifically, we will go over:
- Secret key encryption — a single key is used for encryption and decryption
- Public Key encryption — two keys are used, one for encryption and another for decryption
- One-way functions — special functions which produce signatures that can be used to verify the authenticity of the original information
In case you want to get started early on understanding security and adding it to your programming toolbox, an excellent collection of Java classes can be found in Resources. These classes provide all of the code needed to implement many of the common techniques for digital signatures, as well as code for encryption and decryption. You may ask, “Why isn’t this code on the various Java Cards?” Be patient and before the end of 1998 you should be able to find smart cards that have this functionally in the ROM. I really don’t recommend that you try to build your own solutions here, since the card manufacturers will optimize the code so that it runs quickly. If you were to port some of the Java programs mentioned above to a Java Card without special support, they would be fairly useless in most cases because the program would run so slowly.
Frequently asked questions
These are some common questions that come from two sources: readers and users in the smart card industry. I have included them as a FAQ.
What is the relationship between PC/SC and OpenCard?
IBM and Bull are actively working on an adapter to PC/SC. I have used this adapter and have provided a small example of it in the Resources section. It is much easier to use than using PC/SC directly in C or C++. I do not recommend writing at the PC/SC level since applications you developed will not be portable and PC/SC based on C and C++. Write to OpenCard or other higher-level standards. In the coming months, we will be providing a more complete OpenCard implementation.
Can I use CyberFlex with PC/SC?
Yes, Schlumberger has extensive documentation on this in the CyberFlex Developers manual.
What is the security model for the CyberFlex cards?
There is a multilevel security model. The cards provide secure mechanisms for loading applications and performing card holder verification. In fact, each Cyberflex supports up to six identities and keys that can be used to secure different applications and data objects. Furthermore, Java applications are prevented from accessing data from other applications by the Java security firewalls. Future cards will support industry-standard encryption algorithms.
Will my CyberFlex program be portable?
Any card written to the Java Card 1.0 API will work with any other Java Card 1.0 API cards. When Java Card 2.0 API cards become available, those cards will not run Java Card 1.0 API programs, since the Java Card 2.0 API is not backward-compatible with the 1.0 API. However, Schlumberger has committed to providing 2.0 API-compliant cards that are backward-compatible with Java Card 1.0 API programs.
Is CyberFlex 2.0 a Java Card?
The Cyberflex 2.0 is a second-generation product compatible with the Java Card 1.0 API. It is licensed from JavaSoft, and runs a Java virtual machine in the card. The Java Card 2.0 API specification has just been finalized, and we are hoping that there will be 2.0 API-compliant Java Cards sometime during the first half of 1998. The concepts learned here still will apply, but the programs will require modifications. So you can wait or you can read on and start learning how to use secure portable computers with storage.
How can I debug my program without downloading it to the card?
This is commonly done by using an emulator.
Can I develop my own security solutions for CyberFlex?
Schlumberger has a CryptoFlex card that is ideal for security, since it has an onboard cryptographic processor capable of handling 1024-bit RSA keys. We expect Schlumberger and other smart card vendors to provide cards combining Java programming with cryptographic processing in 1998.
Conclusion
We have shown how you can use the Schlumberger Java Card kit to develop a Java Card application. As time goes on, we expect that the 2.0 Java Card specification will greatly simplify the development of these applications.
The examples in this article demonstrated how to develop Java Card applications based on the 1.0 Java Card API. We were able to use various JDKs to compile Java programs into class files in a 100% Java environment. Schlumberger has a Java version of MakeSolo as well, but it does not have a good class file scrambler so it hasn’t included it in its development kit yet. As for the IDE, Schlumberger has a simulator that relies on the Swing set, which may be released with the non-beta release of Swing from JavaSoft.
Stay tuned for further articles in this area. In May we hope to end this series with 100% Java development tools, including the IDE. I know this is a long wait — but I promise it is worth it. In the interim, use the PC/SC adapters to use smart cards on Windows platforms. And stay tuned to the OpenCard site.