Excited to tell you that our welfare activity has been upgraded - Paying only $5.00 + Freight to get JCOP J3H145 card and A40CR card.
Please check this post for more details.

Moreover, if you want to get Free Samples by Paying Freight only , please check this page.

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 :184
Contact:

SW_ILLEGAL_USE returned by cipher.dofinal()

Post by 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: 39
Joined: Thu Sep 17, 2015 11:50 pm
Points :246
Contact:

Re: SW_ILLEGAL_USE returned by cipher.dofinal()

Post by 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 :184
Contact:

Re: SW_ILLEGAL_USE returned by cipher.dofinal()

Post by 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 :110
Contact:

Re: SW_ILLEGAL_USE returned by cipher.dofinal()

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

Post Reply Previous topicNext topic

Who is online

Users browsing this forum: Google [Bot] and 4 guests

JavaCard OS : Disclaimer