Smart Card Solution
User Manual
- R502 Manual
JavaCard API Samples
- Algorithm
Java Card Specification
Knowledge Sharing
Smart Card Solution
User Manual
JavaCard API Samples
Java Card Specification
Knowledge Sharing
This is an old revision of the document!
Download Sample Code Discussion
/* * @file DESSample.java * @version v1.0 * Package AID: 4A617661436172644F53 * Applet AID: 4A617661436172644F5302 * @brief The ALgorithm of DES Sample Code in JavaCard API Specification * @comment The purpose of this example is only used to show the usage of API functions and there is no practical significance. * @copyright Copyright(C) 2016 JavaCardOS Technologies Co., Ltd. All rights reserved. */ package JavaCardOS.Sample.Algorithm; import javacard.framework.*; import javacard.security.KeyBuilder; import javacard.security.*; import javacardx.crypto.*; public class DESSample extends Applet { private static final byte INS_SET_DES_KEY = (byte)0x20; private static final byte INS_SET_DES_ICV = (byte)0x21; private static final byte INS_DO_DES_CIPHER = (byte)0x22; private byte desKeyLen; private byte[] desKey; private byte[] desICV; private Cipher desEcbCipher; private Cipher desCbcCipher; private Key tempDesKey2; private Key tempDesKey3; public DESSample() { desKey = new byte[32]; desICV = new byte[8]; desKeyLen = 0; //Create a DES ECB/CBS object instance of the DES algorithm. desEcbCipher = Cipher.getInstance(Cipher.ALG_DES_ECB_NOPAD, false); desCbcCipher = Cipher.getInstance(Cipher.ALG_DES_CBC_NOPAD, false); //Creates uninitialized TDES cryptographic keys for signature and cipher algorithms. tempDesKey3 = KeyBuilder.buildKey(KeyBuilder.TYPE_DES_TRANSIENT_DESELECT, KeyBuilder.LENGTH_DES3_3KEY, false); JCSystem.requestObjectDeletion(); } public static void install(byte[] bArray, short bOffset, byte bLength) { new DESSample().register(bArray, (short) (bOffset + 1), bArray[bOffset]); } public void process(APDU apdu) { if (selectingApplet()) { return; } byte[] buf = apdu.getBuffer(); short len = apdu.setIncomingAndReceive(); switch (buf[ISO7816.OFFSET_INS]) { case INS_SET_DES_KEY: //SET_DES_KEY setDesKey(apdu, len); break; case INS_SET_DES_ICV: //SET_DES_ICV setDesICV(apdu, len); break; case INS_DO_DES_CIPHER: //DO_DES_CIPHER doDesCipher(apdu, len); break; default: ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); } } //Set the key of TDES Encrypt/Decrypt private void setDesKey(APDU apdu, short len) { byte[] buffer = apdu.getBuffer(); byte keyLen = 0; switch (buffer[ISO7816.OFFSET_P1]) { case (byte)0x01: // The length of key is 16 bytes if (len != 16) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } keyLen = (byte)16; break; case (byte)0x02: if (len != 24) // The length of key is 24 bytes { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } keyLen = (byte)24; break; default: ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); break; } JCSystem.beginTransaction(); //Copy the incoming TDES Key value to the global variable 'desKey' Util.arrayCopy(buffer, ISO7816.OFFSET_CDATA, desKey, (short)0, len); desKeyLen = keyLen; JCSystem.commitTransaction(); } //Set DES ICV, ICV is the initial vector private void setDesICV(APDU apdu, short len) { if (len != 8) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } //Copy the incoming ICV value to the global variable 'desICV' Util.arrayCopy(apdu.getBuffer(), ISO7816.OFFSET_CDATA, desICV, (short)0, (short)8); } //Get the key that set into the 'desKey' in setDesKey() function, and return the DESKey object. //The plain text length of input key data is 8 bytes for DES, 16 bytes for 2-key triple DES and 24 bytes for 3-key triple DES. private Key getDesKey() { Key tempDesKey = null; switch (desKeyLen) { case (byte)16: tempDesKey = tempDesKey2; break; case (byte)24: tempDesKey = tempDesKey3; break; default: ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); break; } //Set the 'desKey' key data value into the internal representation ((DESKey)tempDesKey).setKey(desKey, (short)0); return tempDesKey; } //DES algorithm encrypt and decrypt private void doDesCipher(APDU apdu, short len) { //In Des algorithm the byte length to be encrypted/decrypted must be a multiple of 8 if (len <= 0 || len % 8 != 0) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } byte[] buffer = apdu.getBuffer(); Key key = getDesKey(); byte mode = buffer[ISO7816.OFFSET_P1] == (byte)0x00 ? Cipher.MODE_ENCRYPT : Cipher.MODE_DECRYPT; Cipher cipher = buffer[ISO7816.OFFSET_P2] == (byte)0x00 ? desEcbCipher : desCbcCipher; //Initializes the 'cipher' object with the appropriate Key and algorithm specific parameters. //DES algorithms in CBC mode expect a 8-byte parameter value for the initial vector(IV) if (cipher == desCbcCipher) { cipher.init(key, mode, desICV, (short)0, (short)8); } else { cipher.init(key, mode); } //This method must be invoked to complete a cipher operation. Generates encrypted/decrypted output from all/last input data. cipher.doFinal(buffer, ISO7816.OFFSET_CDATA, len, buffer, (short)0); apdu.setOutgoingAndSend((short)0, len); } }
The test script of DES is as follows: Download Test Script
//The test script of DES //Copyright(C) JavaCardOS Technologies Co., Ltd. All rights reserved. //DES Select Applet 00A404000B4A617661436172644F530200; //TDES-CBC Encrypt //set Key 802002001810E976F89D2561A110E976F89D2561A110E976F89D2561A1; //set IV 802100000830E91111589CB432; //CBC Encrypt //expect:3C9C65A69E27BB0B9000 802200010841E47B250441B4CA; //set Key 80200200181FC43761574676981FC43761574676981FC4376157467698; //set IV 8021000008B7B2CE02BFAEDFFF; //CBC Encrypt //expect:A22511500C94F0B3AEA0B25F30CB3F839000 8022000110C2EF8033D8D87B5A57C7AE00E6D0AEF5; //3DEC-CBC Decrypt // set Key 80200200187CB5F79EC8897C387CB5F79EC8897C387CB5F79EC8897C38; //set IV 8021000008A25B018DA1AC6A81; //CBC Decrypt //expect:7F34DBAA1FA3848D8EF325ED4E291F13D9C6C8A8B10EA21C0ACADF9D8642413B9000 8022010120FD9B328DCC0C86DD36FB6A559E94720D4C4C47D4620C4274119139370C1399A9; //3DES-ECB Encrypt //set Key 80200200184CDA838AA42AD02A4CDA838AA42AD02A4CDA838AA42AD02A; //ECB Encrypt //expect:0DEAC65F762C8A819000 8022000008869300AFABCF8C8B; // set Key 8020020018f4d04345e01c68f4f4d04345e01c68f4f4d04345e01c68f4; //EBC Decrypt //expect:86104538adf59381f490f78eff7c32f137d3085e2a9d7780de94cecaa6c0f7b29000 8022010020251b7467867536fa8590da6b5bd30266536de9c72c32ec0abfa74a02e25828ce;