Use software components to deploy applications with Java Cards

A URL-based approach for deploying smart cards on different systems

In much of Europe, smart card technology has taken the tedium out of many forms of ebusiness, freeing consumers from having to provide personal information every time they want to conduct a transaction. Java Cards, available in the US today, provide a platform for the easy deployment of multifunctional smart-card applications; unfortunately for US companies and consumers, however, they have yet to catch on here. How can the US close the smart card gap and finally realize the potential of this underused technology?

One way is to develop applications for smart cards that provide consumers and corporate users with convenient and secure methods to access services. With the right kind of smart-card applications, users will be able to avoid the tedium of repeatedly typing information on Web pages in order to conduct secure transactions. The possibilities are great. In some countries, smart cards have eliminated the need for cash, credit cards, or debit cards. But we in the US are still struggling with upgrading point-of-sale terminals in stores to accept smart cards.

And our woes don't end there. Even after typical US consumers wade through multiple layers of pages on the Web in order to carry out secure transactions, they are often reduced to repeating standard information -- name, address, phone number -- over the phone. Worse yet, we must frequently physically send that information out by surface mail once we've begun a transaction over the telephone. Wouldn't it be nice to simply send the data from your smart card? (Smart cards would also reduce the neck and shoulder pain that results from having to balance the phone for long periods of time!) Smart cards can provide a sophisticated means of doing secure transactions and pack the whole process into a small, simple-to-use storage device. In short, they give developers the opportunity to create convenient and much-needed services for users.

Trial and error

There have been many smart card trials and pilots by forward-thinking companies, but few of these programs have generated much excitement or additional value to the consumer. The trials generally lacked integration with the Web, and thus could not showcase such exciting smart-card technologies as instant authentication and affinity programs. In these trials, users still had to enter form information over and over again, prove their identity with less secure methods such as passwords -- or worse yet, social security numbers -- and fall back on paper coupons, rather than just using a smart card with a coupon in its memory.

We can do much better. The technology exists now, and the basic resources to deploy Java Card-capable platforms are easy for Java developers to understand. For online use, you need to be able to load an application on the card that works with some network-based service. We will provide fully coded and tested examples of three services for the Smart Card URL Programming Interface (UPI), an architecture developed at Sun Labs and discussed in September's installment of JavaWorld's Java Developer column. See the Resources section for links to general smart-card information.

We will also explain how to implement an end-to-end solution using Java Card technology in great detail, via documented code examples. Our discussion focuses on the Cyberflex access card manufactured by industry leader Schlumberger Ltd., but the techniques are general and could easily be applied to any Java Card-compliant smart card, such as Dallas Semiconductor Java iButtons, GemPlus GemExpresso cards, smart cards from De La Rue, Bull Information Systems, and even Mondex cards (which are issued by banks that have licensed the Mondex technology). For more information on using the Smart Card UPI to deploy digital cash solutions, take a look at the Resources section. For details on the Cyberflex Access card loading process, see the Loading a Cyberflex Access card sidebar. The converted applet file (CAP) format sidebar is also important to read because all future Java Card-compliant smart cards will support the CAP file format.

The Java Card solution

Let's get started by discussing how to deploy a general-purpose Java Card-based technology that allows you to build applications that support strong authentication, secure personal storage, virtual ATM, and micro- and macropayments. (For the noneconomists in the crowd, micropayments refer to payments less than one dollar, and macropayments refer to larger payments, like 9.95.) Payment options on the Web are currently quite unsophisticated. There is no widespread deployment of support for such services as "pay as you go," daily and weekly payments, subscriptions, and so on. Current payment systems are too heavyweight and require so many transactions that micropayments are not economically feasible.

In solving these problems, we will first discuss how to write an OpenCard service, followed by two specific examples with fully documented Java source code, followed by the source code for a Java Card applet that implements the services needed by SecureTokenHandler on the smart card. Before going into the source code, the following three high-level summaries list the functionality provided by the SecureTokenHandler, JavaCardLoaderHandler, and CorporateCard.

The SecureTokenHandler supports the following UPI. For more detailed information, consul previous articles in JavaWorld which discuss the UPI. Each of the items below is decoded by SecureTokenHandler to produce the desired result. Suppose, for example, that you wanted to get the ID of a smart card. You would send the card a URL of the from:

http://localhost:1234/SecureTokenHandler/GetID

The handler would take the URL, parse and determine which command it is being sent, then return the values to you as either a name/property pair or as a Web page, depending on your configuration options.

  • GetID: Returns the card number of the current card (card numbers are assigned by the application).

  • GetPurse: Returns all currencies and/or tokens supported.

  • GetInfo: Returns general information about the card.

  • CheckPin: Given a PIN, returns a message digest based on SHA1, XOR, or the like.

  • VerifyPin: Verifies a given digest. Usually done with a server.

  • ChangeSetPin: Changes or modifies user PINs.

  • ValueTransfer: Performs a value transfer (requires a server SecureTokenHandler).

  • Decrypt: Decrypts the input data, with optional type.

  • ValueTransfer: Encrypts the input data, with optional type.

The UPIs for loading cards support a few additional commands above and beyond LoadCardFromURL. They work in a similar fashion to those described above; in fact, all handlers work this way. Take CardType, for example. If you issued the following URL:

http://localhost:1234/Loader/CardType

then the handler would return the card type as a string that can be used to create a correct loading profile for the card in question. This type of approach will be demonstrated at Cartes 99 in Paris by platform seven; see Resources for more information.

The JavaCardLoaderHandler supports the following UPI:

  • LoadJavaCardFromURL: The given URL is used to get information to load an applet onto a card. See the sidebar for more information on load file format.

  • CardType: Queries the handler for type of card (e.g., GemExpresso, Java iButton)

  • EndLoad: Tells loader to quit posting status.

  • Status: Returns an interactive status of the load.

The CorporateCard applet, which can load on to any Java Card-compliant smart card, provides the services via the Application Data Protocol Units (APDUs) needed to perform an operation -- to authenticate, for example. A specific APDU command is built by the JavaCardCCProxyService, which implements PurseCardService. The more important methods are listed below. Consult the source listing for more detail.

Writing an OpenCard service

Let's try to break down the functionality we need into software components that we can connect to get our system built. We'll first describe this functionality, then provide some code that realizes the functionality described. We will require the following:

  • The ability to put Java Card applets onto a user's personal Java Card using a browser. This functionality will require a loader OpenCard service to manage the details of loading. You don't just copy applications onto smart cards. Installing an application on a smart card often requires the use of a very specific protocol. Two of the sidebars to this article describe this process, and we have also provided a specific example for Schlumberger, as well as a likely future direction in this area, using the CAP file format.

  • A Java Card applet that implements needed functionality, such as authentication, secure personal storage, micro- or macropayments, signature services, and encryption/decryption services.

  • A proxy for the Java Card applet that runs on the user's host computer. The proxy communicates with the applet-sending and -receiving data in the specific APDUs for the card. This proxy is best realized as an OpenCard service. The Resources section offers examples from previous JavaWorld articles.

  • A UPI handler that takes requests from a user's browser and maps the requests to methods in the proxy, which then communicates with the applet running on the smart card. This technology was described briefly in September's Java Developer. Suppose you wanted to use a card to generate a signature for some data that you want it to send, and then use a different card to verify that data. Sending the following URL (making sure it remains a unified URL, though it has been broken up on your browser screen due to its length):

    http://localhost:4321/SecureTokenServices/
           CheckPin?pin=$$$$java&random=01020304050607
    

    produces the following results, which are returned as name-value pairs:

    purse=1000200030004000

    validate=dd4d255954ad5a1a8e9a201fa6c9cf47f4521f82

    MACTYPE=SHA1

    The smart card has signed the following 64 byte block:

    0000: 4A 61 76 61 4F 6E 65 2B 01 02 03 04 05 06 07 31 JavaOne+.......1

    0010: 30 30 30 32 30 30 30 33 30 30 30 34 30 30 30 80 000200030004000.

    0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

    0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F8 ................

    The server or other party can verify the identity by performing the following operation with its own local SecureTokenServices handler:

    http://localhost:1234/sts/VerifyPin?MACTYPE=SHA1&random=01020304050607
    &validate=dd4d255954ad5a1a8e9a201fa6c9cf47f4521f82&purse=1000200030004000
    

    The server generates the same block of data and generates a digest. If the two digests match, then it's clear that the data was generated by a user possessing a smart card with the secret and the signature algorithm. This example is meant to be introductory. To gain a better understanding of the concepts, look at the Resources section.

In prior JavaWorld articles on Java Card, we discussed how to write OpenCard services. A very quick overview of writing a service follows for those of you who have some knowledge of it. In order to refresh your memory, a simple service for sending APDUs to a card and getting a response can be found in PassThroughCardService.html.

The OpenCard Cyberflex Access loader service

Schlumberger provides the necessary APDUs to load a Java Card application on the card. Tips on writing the application for earlier versions of the card are listed in Resources below. The loader service for the Cyberflex Access card can be found in Loader.html. The OpenCard loader service for a Cyberflex Access card service follows:

1 2 Page 1
Page 1 of 2