Christmas is coming!

To celebrate the new year and thank for the support from all our dear customers, Christmas promotional activity is being held in JavaCardOS online store.

During the event, you can enjoy many promotional activities - High Discount on JavaCardOS products,Lucky Draw,Double forum Points.

Come to choose your own Christmas gift and try your luck now!

SW_ILLEGAL_USE returned by cipher.dofinal()

JavaCard Applet Development Related Questions and Answers.
kineri
Posts: 19
Joined: Thu Dec 10, 2015 2:04 am
Points: 180
Contact:

SW_ILLEGAL_USE returned by cipher.dofinal()

Postby kineri » Mon Oct 16, 2017 2:14 am

I try to encrypt/decrypt with DES. I got an error SW_ILLEGAL_USE when calling decode() but it works fine for encode(). And I cannot find out where is the problem? Could anyone help me? Thanks.

Code: Select all

import javacard.framework.*;
import javacard.security.*;
import javacardx.crypto.*;


public class MyApplet extends Applet{
     
        final static byte ENCODE = (byte)0x22;       
        final static byte DECODE = (byte)0x23;       

        /* codes for errors */
            final static short SW_VERIFY_FAIL            = 0x6A81;
     final static short SW_GENKEY_FAIL            = 0x6A82;
     final static short SW_NO_ALGORITHM           = 0x6A83;
     final static short SW_ILLEGAL_USE            = 0x6A84;
     final static short SW_ILLEGAL_VALUE          = 0x6A85;
     final static short SW_INVALID_INIT           = 0x6A86;
     final static short SW_UNINITIALIZED_KEY = 0x6A87;
       
        private byte[] echoBytes;
        private byte[] encodedBytes;
        private KeyBuilder myKeyBuilder;
        private DESKey myKey;
        private Cipher myCipher;
        // default key :
        private byte[] keyArray = {(byte)0x00,(byte)0x01,(byte)0x02,(byte)0x03,(byte)0x04,(byte)0x05,(byte)0x06,(byte)0x07,(byte)0x08,(byte)0x09,(byte)0x0a,(byte)0x0b,(byte)0x0c,(byte)0x0d,(byte)0x0e,(byte)0x0f};                   
        private static final short LENGTH_ECHO_BYTES = 256;
     public static void install(byte[] bArray, short bOffset, byte aidLen)
     throws ISOException {
          new MyApplet();
     }
     
        private MyApplet() {         
                echoBytes = new byte[LENGTH_ECHO_BYTES];
               
                myKey = (DESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_DES,KeyBuilder.LENGTH_DES, false);
                myKey.setKey(keyArray, (short)0);
                myCipher = Cipher.getInstance( Cipher.ALG_DES_CBC_ISO9797_M2, false);
                myCipherDec = Cipher.getInstance( Cipher.ALG_DES_CBC_ISO9797_M2, false);
               
                register();
     }     

     public void process(APDU apdu) throws ISOException {

          byte[] buffer = apdu.getBuffer();
          switch (buffer[ISO7816.OFFSET_INS]) {
            case ENCODE:     
                    encode(apdu);     
                    break;
                case DECODE:     
                    decode(apdu);     
                    break;
                default:
               ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
          break;
          }
     }
       
        private void encode(APDU apdu) {
   
            byte[] buffer = apdu.getBuffer();
 
            //initialize algorithm with default key
            myCipher.init( myKey, Cipher.MODE_ENCRYPT );
            // data length
            short length = (short)(buffer[ISO7816.OFFSET_LC] & 0xFF);
            //use data in
            apdu.setIncomingAndReceive();
            //compute
            try{
                myCipher.doFinal( buffer, (short)ISO7816.OFFSET_CDATA, (short)16, buffer, (short) 0 );
            }
            catch(CryptoException e){
                explainCryptoExceptions(e);               
            }
            //send
            apdu.setOutgoingAndSend((short)0,length);
        }       

        private void decode(APDU apdu) {
           
             byte[] buffer = apdu.getBuffer();
            //initialize algorithm with default key
            myCipher.init( myKey, Cipher.MODE_DECRYPT);
            // data length
            short length = (short)(buffer[ISO7816.OFFSET_LC] & 0xFF);
            //use data in
            apdu.setIncomingAndReceive();
            //compute
            try{
                myCipher.doFinal( buffer, (short)ISO7816.OFFSET_CDATA, (short)16, buffer, (short) 0 );
            }
            catch(CryptoException e){
                explainCryptoExceptions(e);               
            }
       
            //send
            apdu.setOutgoingAndSend((short)0,length);
        }
       
        private void explainCryptoExceptions(CryptoException e)
     {
          if(e.getReason() == CryptoException.NO_SUCH_ALGORITHM)
               ISOException.throwIt(SW_NO_ALGORITHM);
          else if(e.getReason() == CryptoException.ILLEGAL_USE)
               ISOException.throwIt(SW_ILLEGAL_USE);
          else if(e.getReason() == CryptoException.ILLEGAL_VALUE)
               ISOException.throwIt(SW_ILLEGAL_VALUE);
          else if(e.getReason() == CryptoException.INVALID_INIT)
               ISOException.throwIt(SW_INVALID_INIT);
          else if(e.getReason() == CryptoException.UNINITIALIZED_KEY)
               ISOException.throwIt(SW_UNINITIALIZED_KEY);
          else
               ISOException.throwIt(ISO7816.SW_UNKNOWN);         
     }
}


Crawford
Posts: 38
Joined: Thu Sep 17, 2015 11:50 pm
Points: 232
Contact:

Re: SW_ILLEGAL_USE returned by cipher.dofinal()

Postby Crawford » Mon Oct 16, 2017 4:55 am

Input data must have a multiple of 8 for decryption.

input='112233....BB' -> 11 bytes
after ISO9797_M2 padding='112233....BB8000000000' -> 16 bytes
after encryption='xxxx...xx' -> 16 bytes

So if you want to get correctly decrypted value, you have to give 16 bytes of encrypted data.

kineri
Posts: 19
Joined: Thu Dec 10, 2015 2:04 am
Points: 180
Contact:

Re: SW_ILLEGAL_USE returned by cipher.dofinal()

Postby kineri » Mon Oct 16, 2017 5:41 am

Many thanks for your help, Crawford. It saved my day.

stanneraustin
Posts: 6
Joined: Fri Jul 07, 2017 12:22 pm
Points: 98
Contact:

Re: SW_ILLEGAL_USE returned by cipher.dofinal()

Postby stanneraustin » Fri Nov 10, 2017 7:55 am

using DES without padding is very weak.
You must use ISO9797_M1 or ISO9797_M2 or PKCS5 so cipher will auto pad it.
also u must not use LENGTH_DES instead use LENGTH_DES3_2KEY or higher for more security of ur project.


Return to “Questions & Answers”

Who is online

Users browsing this forum: No registered users and 1 guest

JavaCard OS : Disclaimer