|| Home || IT Security || Smart cards || Resources || Links || switch_to_cz

Cryptographic algorithms re-implementation for JavaCard

Last update: 9.7.2009

The set of cryptographic algorithms supported by the particular JavaCard smart card is not usually covering all algorithms specified in JavaCard specifications. This page provides some software re-implementation of selected cryptographic algorithms for JavaCard, optimized for speed and low memory/code footprint (but do not expect similar performance as with natively supported algorithms). Code is available under BSD-style license. If you are instead interested in obtaining set of algorithm natively supported by your smart card, follow to the JavaCard's algorithms support test

Following algorithms are now available:
You may be also interested in:

Advanced Encryption Standard (AES) with 128bit key

Software re-implementation of AES with 128-bits key usable for JavaCard. Optimized for speed and relatively low memory footprint. You need only one JavaCardAES object for multiple different keys - scheduled keys are created to (or used from) external array so you do not need multiple objects or key rescheduling when switching between different keys.

arrow Download source code here : JavaCardAES.java.

    // allocate engine
    JavaCardAES aesCipher = new JavaCardAES();
    // set array with initiualization vector
    aesCipher.m_IV = array_with_IV;
    aesCipher.m_IVOffset = 0;

    // schedule keys for first key into array array_for_round_keys_1
    aesCipher.RoundKeysSchedule(array_with_key1, (short) 0, array_for_round_keys_1);
    // encrypt block with first key
    aesCipher.AESEncryptBlock(data_to_encrypt, start_offset_of_data, array_for_round_keys_1);

    // schedule keys for second key into array array_for_round_keys_2
    aesCipher.RoundKeysSchedule(array_with_key_2, (short) 0, array_for_round_keys_2);
    // decrypt block with second key
    aesCipher.AESDecryptBlock(data_to_decrypt, start_offset_of_data, array_for_round_keys_2);

SHA2-384 and SHA2-512 cryptographic hash functions

Software re-implementation of SHA2 cryptographic hash function usable for JavaCard. Optimized for speed and relatively low memory footprint. You need only one Sha2 object. Separate data arrays can be hashed via update() function.

arrow Download source code here : Sha2.java and Int_64.java.

  // allocate SHA2 engine (use SHA_512 or SHA_384 constant)
  Sha2 sha2 = new Sha2(Sha2.SHA_512);
  // reset internal state of engine
  // call (possibly multiple times) update function over parts of data you like to hash
  sha2.update(array_to_hash, start_offset_of_data, hash_data_length);
  // finalize hashing and read out hash result into array_for_hash_output array
  sha2.doFinal(another_part_of_array_to_hash, start_offset_of_data, hash_data_length, array_for_hash_output, start_offset_of_hash_output);

Optimal Asymmetric Encryption Padding (OAEP)

Software re-implementation of OAEP padding scheme decoding usable for JavaCard. Optimized for speed and relatively low memory footprint. You need only one OAEP object. Only OAEP decoding is possible at the moment (but is not hard to add also encoding direction). Note that OAEP uses internally a lot of hash function invocation - better to have hash function natively supported by smart card, but can be also combined with re-implemetation of SHA-2 code.

arrow Download source code here : JC_OAEP.java.

  // allocate OAEP engine
  JC_OAEP oaep = new JC_OAEP();
  // initialze cipher engine (e.g., RSACipher), hash engine (e.g., Sha1),
  // optional_encoding_parameters_can_be_null .. optional encoding parameters (can be null, if not used),
  // NOTE: external_array_for_internal_work_can_be_null ... array used for internal computations
  // (if null then array will be allocated interally) - should be RAM array for reasonable speed. But you can reuse existing array to save resources.
  // If you will use let array to be allocated internally,
  // set MAX_MASK_ARRAY_LENGTH to proper value (depending on cipher modulus - 200B is fine for RSA 2048 with SHA2-512)
  oaep.init(false, cipher_engine, hash_engine, optional_encoding_parameters_can_be_null, external_array_for_internal_work_can_be_null);

  // decode block of data from OAEP encoded block
  decLen = oaep.decodeBlock(data_to_decode, start_offset_of_data, length_of_data);

Please, report any bugs or suggestions to my mail (see footer of the page). Thank you!

OpenPGP key : 0x89CEB31C