We are very excited to launch a brand new product - LibSC Reader Kit.

LibSC Reader Kit developed by JavaCardOS Technologies is implemented based on Arduino hardware platform and this kit provides simple universal card reader's functions.

And this time we have launched two kinds of development kit - LibSC Reader Kit and LibSC Reader Kit pro.

Please check this page for more release details.

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: 3
Joined: Fri Jul 07, 2017 12:22 pm
Points: 46
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: Baidu [Spider] and 1 guest

JavaCard OS : Disclaimer