JavacardOS will not accept order any more, please contact our partner Feitian online Store:
https://ftsafe.en.alibaba.com/index.html

The ALgorithm of DES Sample Code

Applets Development Guide

Moderator: product

User avatar
JavaCardOS
Posts: 273
Joined: Thu Apr 30, 2015 12:00 pm
Points :2405
Contact:

The ALgorithm of DES Sample Code

Post by JavaCardOS » 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.


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 .
You do not have the required permissions to view the files attached to this post. Please login first.

initialdhi
Posts: 7
Joined: Mon Oct 03, 2016 4:10 am
Points :96
Contact:

Re: The ALgorithm of DES Sample Code

Post by initialdhi » Sat Oct 29, 2016 4:54 am

how I can decrypt byte from this applet in java application (terminal application) ?


tay00000
Posts: 161
Joined: Tue Sep 27, 2016 10:58 am
Points :2324
Contact:

Re: The ALgorithm of DES Sample Code

Post by tay00000 » Mon Oct 31, 2016 10:15 am

Code: Select all

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();


This can be optimized by using the setKey() function.

Code: Select all

tempDesKey2.setKey(buffer, ISO7816.OFFSET_CDATA);


All it needs is 1 line of code versus the above 5 lines of codes to set a key. I would also highly recommend not to use JCSystem's transaction mechanism whenever not needed as I am currently coding for NXP JCOP 2.4.3 smart card and it doesn't handle beginTransaction/commitTransaction for key data especially RSA 2048 bit keys (off-topic but related). In the end, setKey() itself should be able to handle the data since the data buffer is directly handed over to the Key object which if you measure the time would take more time for the original code than the code I presented. Also, you don't need the desKeyLen anymore since all you need to do is check input against 8/16/24 bytes of input with a single if statement via ...

Code: Select all

if((short) (buffer[ISO7816.OFFSET_LC] & 0xFF) == 16 || (short) (buffer[ISO7816.OFFSET_LC] & 0xFF) == 24) {
    tempDesKey2.setKey(buffer, ISO7816.OFFSET_CDATA);     
}


You would have effectively speed up the entire process of checking the key length and also loading the key into the DESKey object with only 3 lines of codes versus the many lines. Also, not to forget to wipe buffer via Util.arrayFillNonAtomic() with (byte) 0x00 since it contains key material - just for safety's sake.

Transaction mechanism is a weird thing and should not be used too often. I get different results from different cards and what I can tell is NXP JCOP 2.4.3 seems to not like the calling of commit or begin transaction and usually throw me exceptions when the Feitian A22CR and Feitian's C21C simply don't mind the transactions. Just some food for thought.

Hope it helps :) .

User avatar
UNKNwYSHSA
Posts: 630
Joined: Thu May 21, 2015 4:05 am
Points :3053
Contact:

Re: The ALgorithm of DES Sample Code

Post by UNKNwYSHSA » Mon Oct 31, 2016 10:04 pm

You means JCOP 2.4.3 raises exception when you use JCSystem.xxxTransaction()? And A22CR do nothing?
sense and simplicity

tay00000
Posts: 161
Joined: Tue Sep 27, 2016 10:58 am
Points :2324
Contact:

Re: The ALgorithm of DES Sample Code

Post by tay00000 » Mon Oct 31, 2016 10:09 pm

Yes. I think this belongs to another topic for the transaction problem.

User avatar
UNKNwYSHSA
Posts: 630
Joined: Thu May 21, 2015 4:05 am
Points :3053
Contact:

Re: The ALgorithm of DES Sample Code

Post by UNKNwYSHSA » Mon Oct 31, 2016 10:19 pm

JCOP 2.4.3:
Mybe the data size in transaction exceeds transaction size?
A22CR:
How you know that? Can you show me the test code?
sense and simplicity

User avatar
UNKNwYSHSA
Posts: 630
Joined: Thu May 21, 2015 4:05 am
Points :3053
Contact:

Re: The ALgorithm of DES Sample Code

Post by UNKNwYSHSA » Mon Oct 31, 2016 10:23 pm

You can create a new post where we can discuss the topic.
Our discussion is already out of this post topic. :D
sense and simplicity

TobyCao
Posts: 1
Joined: Thu May 23, 2019 2:46 am
Points :16
Contact:

Re: The ALgorithm of DES Sample Code

Post by TobyCao » Thu May 30, 2019 5:02 am

I just fix one bug. :D

  1.   public ThirdDemo()
  2.  
  3.     {
  4.  
  5.         desKey = new byte[32];
  6.  
  7.         desICV = new byte[8];
  8.  
  9.         desKeyLen = 0;
  10.  
  11.       //Create a DES ECB/CBS object instance of the DES algorithm.
  12.  
  13.         desEcbCipher = Cipher.getInstance(Cipher.ALG_DES_ECB_NOPAD, false);
  14.  
  15.         desCbcCipher = Cipher.getInstance(Cipher.ALG_DES_CBC_NOPAD, false);
  16.  
  17.       //Creates uninitialized TDES cryptographic keys for signature and cipher algorithms.
  18.  
  19.         [b]tempDesKey2 = KeyBuilder.buildKey(KeyBuilder.TYPE_DES_TRANSIENT_DESELECT, KeyBuilder.LENGTH_DES3_2KEY, false);[/b]
  20.  
  21.         tempDesKey3 = KeyBuilder.buildKey(KeyBuilder.TYPE_DES_TRANSIENT_DESELECT, KeyBuilder.LENGTH_DES3_3KEY, false);
  22.  
  23.         JCSystem.requestObjectDeletion();
  24.  
  25.     }

Shrutiii
Posts: 1
Joined: Fri Dec 27, 2019 1:55 am
Points :12
Contact:

Re: The ALgorithm of DES Sample Code

Post by Shrutiii » Fri Dec 27, 2019 1:57 am

Hi!
Excellent ! I got useful information here. Thank you!

Post Reply Previous topicNext topic

Who is online

Users browsing this forum: No registered users and 8 guests

JavaCard OS : Disclaimer