JavaCard Applet Development
Building and deploying applets on JavaCard smart cards.
JavaCard Applet Development
JavaCard is the Java platform for resource-constrained smart cards. It defines a strict subset of Java SE — no floating point, no threads, no dynamic class loading — tuned to run on processors with as little as 2 KB of RAM and 64 KB of non-volatile memory. Despite these constraints, JavaCardJavaCardSoftwareJava applet platform for smart cards.Click to view → enables portable, multi-vendor applet deployment that underpins billions of SIMSIMApplicationSmart card for mobile network authentication.Click to view →, banking, and identity cards worldwide.
Use the APDU Builder to construct and send raw APDUs to your applet during development without writing a full host application.
JavaCard API Essentials
The JavaCard API is organised into packages under javacard.* and javacardx.*.
The two most important packages for any applet are:
| Package | Key classes | Purpose |
|---|---|---|
javacard.framework |
Applet, APDU, ISO7816, JCSystem, OwnerPIN |
Applet skeleton, APDUAPDUProtocolCommunication unit between card and reader.Click to view → handling, system calls |
javacard.security |
KeyBuilder, Signature, Cipher, MessageDigest, RandomData |
Cryptographic primitives |
javacardx.crypto |
Cipher (symmetric) |
AESAESCryptographyNIST symmetric block cipher for smart card encryption.Click to view →/3DES3DESCryptographyLegacy triple-DES symmetric cipher in payment smart cards.Click to view → cipher objects |
javacard.framework.service |
BasicService, CardRemoteObject |
RMI-style remote objects |
org.globalplatform |
GPSystem, SecureChannel |
GlobalPlatform integration |
All cryptographic objects must be instantiated during applet installation and stored in instance variables — not created on every APDU, because object creation allocates EEPROM write cycles and is slow.
Applet Lifecycle
A JavaCard applet follows the GlobalPlatform lifecycle and exposes three callback methods that the card runtime invokes:
install() → Applet object created and registered with the card runtime
↓
select() → Called when host sends SELECT AID ([AID](/glossary/aid/))
↓ Returns true to accept selection, false to decline
process() → Called for every subsequent APDU until next SELECT or reset
↓
deselect() → Called when another applet is selected or card reset occurs
The process() method is the heart of any applet. It receives the APDU object,
reads the command bytes, dispatches to the appropriate handler, and writes the
response — all within a single method call.
APDU Handler Pattern
A well-structured APDU handler dispatches on the INS byte and validates input length before touching any sensitive data:
public void process(APDU apdu) {
byte[] buf = apdu.getBuffer();
if (selectingApplet()) return; // implicit 90 00 on SELECT
byte ins = buf[ISO7816.OFFSET_INS];
switch (ins) {
case INS_VERIFY_PIN:
verifyPin(apdu);
break;
case INS_SIGN:
signData(apdu);
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
Key patterns to follow:
- Always call
apdu.setIncomingAndReceive()before reading Lc-length data - Validate Lc and Le before cryptographic operations to prevent oracle attacks
- Use
JCSystem.makeTransientByteArray()for temporary buffers — transient arrays live in RAM and are cleared on card reset, preventing leakage across sessions - Never return sensitive data unconditionally — check PIN status or session authentication state before writing key material to the response buffer
Debugging and Testing
JavaCard simulation frameworks allow applet testing on a desktop before loading to physical hardware:
| Tool | Vendor | Interface |
|---|---|---|
| jCardSim | Open source | Java API + virtual APDU transport |
| Eclipse JCDE | NXP | Full IDE integration |
GlobalPlatformGlobalPlatformSoftwareCard application management standard.Click to view →-tools (gp) |
Open source CLI | Load/install/delete via PC/SC |
OpenSC pkcs15-tool |
Open source | PKCS#15 applet introspection |
Use the APDU Builder to compose raw byte-level commands for
regression testing applet branches that higher-level tools do not exercise. Always
test all error paths (wrong PIN, wrong length, wrong P1/P2) because incorrect
ISOException handling is a common source of information leakage.
Persistent vs Transient State
JavaCard distinguishes two memory regions with very different semantics:
| Memory | Location | Cleared on reset? | Write endurance | Cost |
|---|---|---|---|---|
| Persistent (EEPROM / flash) | Non-volatile | No | ~500,000 writes | High (wear) |
| Transient (CLEAR_ON_RESET) | RAM | Yes, on card reset | Unlimited | Low |
| Transient (CLEAR_ON_DESELECT) | RAM | Yes, on deselect | Unlimited | Low |
Minimising persistent writes is critical for card longevity. Use transient arrays for cryptographic buffers, temporary results, and session state. Reserve persistent memory for keys, counters, and application data that must survive power cycles.
See APDU Command Reference for the full command set your applet can implement, and GlobalPlatform Card Management for how to load and manage your compiled CAP file on a real card.
Frequently Asked Questions
JavaCard is a subset of the Java programming language and platform optimized for resource-constrained smart card chips. It omits many Java features unavailable on cards — no floating point, no threads (except firewall-isolated contexts), no garbage collection in early versions, and limited primitive types. JavaCard applications (applets) extend `javacard.framework.Applet` and are managed by the JavaCard Runtime Environment (JCRE) on the card's OS.
GlobalPlatform (GP) defines the card management layer that operates above the JavaCard runtime — specifically, how applets are securely installed, personalized, and deleted on a card in the field. GP specifies the Secure Channel Protocol (SCP02, SCP03) used by card management systems to authenticate and encrypt APDU sessions, and defines the Issuer Security Domain (ISD) and supplementary security domains for multi-application card environments.
JavaCard distinguishes between persistent memory (EEPROM/flash), which survives power loss and card reset, and transient memory (RAM), which is cleared on card reset (CLEAR_ON_RESET) or deselect (CLEAR_ON_DESELECT). Instance variables in applet objects are persistent by default. Developers must explicitly use `JCSystem.makeTransientByteArray()` for sensitive session data to avoid leaking secrets across transactions via EEPROM.
The primary development toolchain is the Oracle JavaCard Development Kit (JDK), which includes a converter tool that transforms class files into CAP (Converted Applet) packages for on-card installation. Testing is done with the JavaCard simulator (jcardsim) for unit tests, followed by testing on physical evaluation boards (e.g., J3H081, JCOP4). GlobalPlatform tools such as GPShell or gp-java-tool manage CAP installation via the GP secure channel.
Our guides cover a range of experience levels. Getting Started guides introduce smart card fundamentals. Security guides address Common Criteria certification and key management. Programming guides target developers working with APDU commands, JavaCard applets, and GlobalPlatform card management.