1 Reply Latest reply: Jan 9, 2013 12:54 PM by Hana Bizhani RSS

    having problem with des encryption in jcwde

    980216
      I have problem with encrypting data using des encryption.... when i debug, it is stopping at the dofinal() method....help needed.



      public class wallet extends Applet {

           public short balance= (short) 22;
           
           
           final static byte Wallet_CLA = ( byte ) 0xB0;
           
           public short isVerified;
           // public short tryCounter;//number of tries for pin
           public byte[] pin=new byte[]{ 0x10, 0x10};
           public byte[] key_array=new byte[]{(byte)0x09,(byte)0x0e,(byte)0x0d,(byte)0x0c,(byte)0x0b,(byte)0x0a,(byte)0x09,(byte)0x08};
           public OwnerPIN m_pin;
           // public Cipher m_cipher;
           public DESKey m_desKey;
           public Cipher m_cipher;

           
           final static byte ENCRYPT= (byte) 0x10;
           final static byte VERIFY = ( byte ) 0x20;
           final static byte CREDIT = ( byte ) 0x30;
           final static byte DEBIT = ( byte ) 0x40;
           final static byte GET_BALANCE = ( byte ) 0x50;
           
           final static short SW_INVALID_DEBIT_AMOUNT = 0x6A83;
           final static short SW_INVALID_CREDIT_AMOUNT = 0x6A84;
           final static short SW_VERIFICATION_FAILED = 0x6A85;
           final static short SW_PIN_BLOCKED = 0x6A86;
           final static short SW_CIPHER_DATA_LENGTH_BAD= 0x6A87;
           
           
           
           private wallet(byte bArray[], short bOffset, byte bLength) {
                isVerified=0;
                //tryCounter=3;
                m_pin = new OwnerPIN((byte) 3, (byte) 4);
                m_pin.update(pin, (short) 0, (byte) pin.length);
                
                m_desKey=(DESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES, false);
                m_desKey.setKey(key_array, (short)0);
                m_cipher =Cipher.getInstance(Cipher.ALG_DES_CBC_ISO9797_M2, false);
                m_cipher.init(m_desKey,Cipher.MODE_ENCRYPT);
                
                
                //register(bArray,(short)(bOffset+1),bArray[bOffset]);
           }

           public static void install(byte bArray[], short bOffset, byte bLength)
                     throws ISOException {
                new wallet(bArray, bOffset, bLength).register();
           }

           public void process(APDU apdu) throws ISOException {
                // TODO Auto-generated method stub

                byte[] buff = apdu.getBuffer();
                
                if(selectingApplet())
                     return;
                
                //byte[] buff = apdu.getBuffer();
                
      if(buff[ISO7816.OFFSET_CLA] == Wallet_CLA)
      {
           
           switch (buff[ISO7816.OFFSET_INS])
           {
           case ENCRYPT:
                encrypt(apdu);
                return;
           case VERIFY:
                verify(apdu);
                return;
           case CREDIT:
                credit(apdu);
                return;
           case DEBIT:
                debit(apdu);
                return;
           case GET_BALANCE:
                getBalance(apdu);
                return;
           default:
                ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
                
                     
           }
      return;     
           
      }

           }

           private void getBalance(APDU apdu) {
                // TODO Auto-generated method stub
           
                if(!(m_pin.getTriesRemaining()>0))
                     ISOException.throwIt(SW_PIN_BLOCKED);
                
                if(!(m_pin.isValidated()))
                     ISOException.throwIt(SW_VERIFICATION_FAILED);
                
                byte[] buffer = apdu.getBuffer();
                
                //buffer[0]=(byte) balance;
                
                apdu.setOutgoing();//indicates apdu has outgoing data
                apdu.setOutgoingLength ( ( short ) 2 ) ; //outgoing data length(le)
                
                //storing balance in buffer array
                buffer [ 0 ] = ( byte ) ( balance >> 8 ) ;
                buffer [ 1 ] = ( byte ) ( balance & 0xFF ) ;
                
                apdu.sendBytes ( ( short ) 0, ( short ) 2 ) ;
                
                //apdu.setOutgoingLength(len)
                
                return;
           }

           private void debit(APDU apdu) {
                // TODO Auto-generated method stub
                
                
                if(!(m_pin.getTriesRemaining()>0))
                     ISOException.throwIt(SW_PIN_BLOCKED);
                
                if(!(m_pin.isValidated()))
                     ISOException.throwIt(SW_VERIFICATION_FAILED);
                
                byte[] buffer = apdu.getBuffer();
                
                byte numBytes=(byte) apdu.getIncomingLength();//number of bytes received
                
                if(numBytes!=1)
                     ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
                
                byte byteRead= (byte)apdu.setIncomingAndReceive();
                
                byte debitAmount=buffer[ISO7816.OFFSET_CDATA];
                
                
                
                if(balance > (short)debitAmount)
                {
                balance=(short) (balance-(short)debitAmount);
                          
                }
                else
                {
                     ISOException.throwIt(SW_INVALID_DEBIT_AMOUNT);
                }
                
                
                
           }

           private void credit(APDU apdu) {
                // TODO Auto-generated method stub
                if(!(m_pin.getTriesRemaining()>0))
                     ISOException.throwIt(SW_PIN_BLOCKED);
                
                if(!(m_pin.isValidated()))
                     ISOException.throwIt(SW_VERIFICATION_FAILED);
                     
                byte[] buffer = apdu.getBuffer();
                
                byte numBytes=(byte) apdu.getIncomingLength();
                
                if(numBytes!=1)
                     ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
                
                //setting the apdu direction as incoming and getting number of bytes
                byte byteRead= (byte)apdu.setIncomingAndReceive();
                
                
                
                byte creditAmount=buffer[ISO7816.OFFSET_CDATA];
                
                
                
                if(creditAmount<0)
                ISOException.throwIt(SW_INVALID_CREDIT_AMOUNT);
                
                balance=(short) (balance+(short)creditAmount);
                     
           }

           private void verify(APDU apdu)
           {
                
                
                byte[] buffer = apdu.getBuffer();
                byte numBytes=(byte) apdu.getIncomingLength();
                byte byteRead= (byte)apdu.setIncomingAndReceive();
                
                //byte pass=buffer[ISO7816.OFFSET_CDATA];
                if(m_pin.getTriesRemaining()>0)//check whether the try limit has been crossed
                     //
                     //if(Util.arrayCompare(buffer, (short)ISO7816.OFFSET_CDATA, pin, (short)0, (short)2)==0)//comparing pins
                     
                     if(m_pin.check(buffer, (short)ISO7816.OFFSET_CDATA,byteRead))
                     {
                     isVerified=1;//setting status as verified
                     
                     
                     
                     }
                     else//wrong password
                     {
                     //tryCounter--;
                     ISOException.throwIt(SW_VERIFICATION_FAILED);
                     }
                else
                {
                     ISOException.throwIt(SW_PIN_BLOCKED);
                     
                }
                
                // TODO Auto-generated method stub
                
                
           }

           private void encrypt(APDU apdu)
           {
                byte[] buffer=apdu.getBuffer();
                
                short bytelen=(short)(apdu.setIncomingAndReceive());
                //short byteRead=(short) (buffer[ISO7816.OFFSET_LC] & 0x00FF);
                byte[] outbuff=new byte[(short)16];
                
                if(((short)bytelen%8)!=0)ISOException.throwIt(SW_CIPHER_DATA_LENGTH_BAD);
                //m_cipher.update(buffer, ISO7816.OFFSET_CDATA, (short)bytelen, outbuff, (short)0);
                
                m_cipher.doFinal(buffer,(short) ISO7816.OFFSET_CDATA, (short)bytelen, buffer, (short)0); //"DEBUGGER STOPS AT THIS LINE"
                
                Util.arrayCopyNonAtomic(outbuff, (short)0, buffer, (short)ISO7816.OFFSET_CDATA, (short)bytelen);
                apdu.setOutgoing();
                apdu.setOutgoingLength((short)bytelen);
                apdu.sendBytesLong(outbuff,(short)ISO7816.OFFSET_CDATA,(short)bytelen);
                //apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, (short)bytelen);
                
           }
      }

      Edited by: 977213 on Dec 16, 2012 10:24 PM
        • 1. Re: having problem with des encryption in jcwde
          Hana Bizhani
          Hi,

          Check out Cipher. dofinal method,
          the 4th parameter should be the destination which is outbuff.

          it shoul be change to :
           m_cipher.doFinal(buffer,(short) ISO7816.OFFSET_CDATA, (short)bytelen, outbuff, (short)0); 
          when I run your code the result was all 00, that was because of this error,
          maybe the debugger has the same problem,
          check it and tell me the result

          Regards,
          Hana