Secure Personalization of Java Card Applets Using Issuer Security Domain and SCP02

The article explains how to leverage the Issuer Security Domain mechanisms on GlobalPlatform cards to establish secure channels for applet personalization without implementing custom ECDH-based key exchange. It addresses limitations of prior approaches that lacked authentication and required extensive PKI support. The solution uses SCP02 with specific security levels such as C_MAC and C_DECRYPTION to protect commands that store AES-128 keys and personal data on the card. Detailed code walkthroughs cover the applet constructor, process method, mutual authentication via SecureChannel.processSecurity, and unwrap operations for decrypting and verifying APDUs. Practical testing on NXP Java Cards demonstrates installation via FunGP library scripts that allow configurable security levels during mutual authentication. The implementation ensures that secret key updates enforce C_DECRYPTION while personal data writes accept C_MAC, with encrypted reads performed using AES-CBC.

HabrTranslated from Russian

Read at source

The tutorial demonstrates an elegant approach to secure Java Card applet personalization by relying on the built-in security features of the Issuer Security Domain instead of custom asymmetric cryptography implementations.

Background and Problem Statement

Previous examples using ECDH for session key derivation required significant testing resources and failed to provide authentication, allowing any party knowing the elliptic curve parameters to extract secrets. The new method avoids these issues by delegating security to the GlobalPlatform card manager.

The use case involves an access control system where employee data (name, department, position, validity period) must be written or updated only by authorized parties over a protected channel. Any reader can retrieve the data, but it is returned encrypted with AES-128. The applet must securely receive and periodically update the 16-byte key throughout the card lifecycle.

Applet Implementation Details

The constructor simply allocates a 255-byte buffer for personal information. Heavy cryptographic objects such as AESKey and Cipher are instantiated after installation to avoid 6F00 errors on NXP cards during the INSTALL for install command.

The install method follows GlobalPlatform guidelines by passing the instance AID to register(). The process method handles three proprietary instructions for setting the secret key, writing personal data, and reading personal data, while unknown instructions are routed to mutual authentication.

A helper method determines whether an instruction carries command data, ensuring setIncomingAndReceive is called only when needed. Comprehensive try-catch blocks convert CryptoException reasons into informative status words instead of generic 6F00 errors.

Secure Channel Usage

The applet obtains a SecureChannel instance in select() via GPSystem.getSecureChannel and resets it in deselect(). Unknown APDUs invoke scp02.processSecurity, which handles INITIALIZE UPDATE and EXTERNAL AUTHENTICATE commands according to the negotiated security level.

The update_secret_key method calls unwrap with an adjusted length to account for the CLA offset, then verifies that the security level includes C_DECRYPTION before installing the AES key. The set_person_info method applies a lower requirement of C_MAC only.

Reading personal information simply initializes the AES cipher in encryption mode and returns the ciphertext. All operations are tested using the FunGP Python library, which supports multiple SCP02 security levels configurable at mutual authentication time.

Meridian digestThe week's most consequential security stories, distilled into one briefing.See the digest

More in Other

Mail.ru Reduces Lifetime 1TB Cloud Storage Promo to Standard 8GB Quota for Select Users
Kimi K3 Open Model Surpasses Closed AI Leaders with Million-Token Context and 896 Experts
Innostage Completes Functional Testing of PT NGFW 1.10.3 Across 156 Criteria