The ALgorithm of DES Sample Code
Posted: Sat Jul 09, 2016 5:58 am
The following code is the ALgorithm of DES Sample Code in JavaCard API Specification.
You can copy and use it directly or you can download the JCIDE project from the attachment and build it.
Note:
The purpose of this example is only used to show the usage of DES algorithm .
You can copy and use it directly or you can download the JCIDE project from the attachment and build it.
Code: Select all
/*
* @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);
}
}
Note:
The purpose of this example is only used to show the usage of DES algorithm .