11 Replies Latest reply: May 3, 2012 4:15 AM by 934529 RSS

    decryption and padding in java cryptography

    934529
      i have to decrypt a frame on my server. encrypted frame is coming from client device through GPRS on socket.encryption is done with "TripleDes" and with a given key.same algorithm and key i am using n server side. frame is a combination of Hex and Ascii String. problem is when i decrypt this frame i get an error :

      javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher

      and when i pad my byte array with zeros like

      temparray[87] = 00;


      i get an error :

      javax.crypto.BadPaddingException: Given final block not properly padded

      following is my code :
          if ((len = inputStream.read(mainBuffer)) > -1) {
                          totalLength = len;
                      }
          if (totalLength > 0) {
                          byteToAscii = function.byteToAscii(mainBuffer, totalLength);
                      }
          if (byteToAscii.length() > 0) {
                          completeHexString = function.stringToHex(byteToAscii);               
                          debugInfo = "FRAME RECV.=" + completeHexString;
          /* FRAME RECV.=41ed34a41a9de6d270aa1e1464527e88c8bee66a00cfb308f60c105de81db0f1ce43d8c0b9bc4e8070b5ab8d4d3650b55d23223fc687bb1485945bc3228e9707a7aecda9f90657e0ac009571c6469c58a2cd9793cc433ccb5993f2*/
                      }
          byte[] key = new byte[]{31, 30, 31, 36, 32, 11, 11, 11, 22, 26, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30};
          myKeySpec = new DESedeKeySpec(key);
          mySecretKeyFactory = SecretKeyFactory.getInstance("TripleDES");
          dekey = mySecretKeyFactory.generateSecret(myKeySpec);
          byte[] zeros = {0, 0, 0, 0, 0, 0, 0, 0};
          IvParameterSpec iv = new IvParameterSpec(zeros);
          Cipher c = Cipher.getInstance("TripleDES/CBC/PKCS5Padding");
          c.init(Cipher.DECRYPT_MODE, dekey, iv);
          byte[] decordedValue = new BASE64Decoder().decodeBuffer(completeHexString);
          byte[] decValue = c.doFinal(decordedValue);
          String decryptedValue = new String(decValue);
          System.out.println("decryptedValue= " + decryptedValue);
      here are the functions which i am using inside the code:
          public String stringToHex(String base) {
                  StringBuffer buffer = new StringBuffer();
                  int intValue = 0;
                  for (int x = 0; x < base.length(); x++) {
                      intValue = base.charAt(x);
                      String hex = Integer.toHexString(intValue);
                      if (hex.length() == 1) {
                          buffer.append("0" + hex + "");
                      } else {
                          buffer.append(hex + "");
                      }
                  }
                  return buffer.toString();
              }
          public String byteToAscii(byte[] b, int length) {
                  String returnString = "";
                  for (int i = 0; i < length; i++) {
                      returnString += (char) (b[i] & 0xff);
                  }
                  return returnString;
              }
      i am new in java cryptography. pl tell me how to do it?
      thanks in advance.
        • 1. Re: decryption and padding in java cryptography
          sabre150
          Surely you should be hex decoding and not base64 decoding! Looking at it again it is not clear to me why you are base64 decoding at all. If the 'completeHexString' value shown is typical then it does not represent a hex encoding of base64 encoded data or double hex encoded data at all. For both base64 and hex the hex decoding of "41ed34a41" should be ASCII characters if the ciphertext is either hex or base64 encoded but 'ed' most definitely is not and ASCII character.

          Edited by: sabre150 on May 2, 2012 3:47 PM
          • 2. Re: decryption and padding in java cryptography
            934529
            thanx 4 ur reply. i have modified my code. i am not decoding it with Base64 now. but now getting the exception "Given final block not properly padded".can you post the code which can work properly to decrypt my frame.
            ------
            Cipher c = Cipher.getInstance("TripleDES");
            c.init(Cipher.DECRYPT_MODE, key);
            int l = completeHexStr.length();
            if (l%8==1) completeHexStr = completeHexStr + "0000000";
            up to-
            else if (l%8==7) completeHexStr = completeHexStr + "0";
            byte decordedValue[] =completeHexString.getBytes();
            byte[] decValue = c.doFinal(decordedValue);
            -------
            • 3. Re: decryption and padding in java cryptography
              EJP
              I am not decoding it with Base64 now.
              You're not decoding it at all now.

              You need to write yourself an inverse function for stringToHex(), and use it.
              • 4. Re: decryption and padding in java cryptography
                934529
                this is the code in c used for encryption at client side.
                #include <svc_sec.h>
                const unsigned char fixed_key[] = { 0x31, 0x30, 0x31, 0x36, 0x32, 0x11, 0x11, 0x11, 0x22, 0x26, 0x30,
                                                          0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30};
                int Comm_Encrypt_Data(unsigned char *Test_Input_Data, int Len_Input_Data)
                {
                      int Count_Input_Data, Counter_Input_Data;
                      unsigned long Timer_1;
                      unsigned char Init_Vector[8];
                      int Counter_Init_Vector, Temp_Byte_Count;
                      unsigned char *Temp_Dst_Ptr, *Temp_Src_Ptr;
                      unsigned char Temp_Input_Frame[9], Temp_Output_Frame[9];
                      unsigned char Test_Output_Data[500];
                      unsigned char Test_Key_Arr[9];
                
                      memset(&Init_Vector[0], '\0', sizeof(Init_Vector));
                      memset(Test_Key_Arr, '0', sizeof(Test_Key_Arr));
                      memcpy(Test_Key_Arr, &fixed_key[0], 8);
                      Test_Key_Arr[sizeof(Test_Key_Arr)-1] = '\0';
                      
                      Display_Data("KEY: ", Test_Key_Arr, sizeof(Test_Key_Arr)-1);
                
                      memset(Test_Output_Data, '\0', sizeof(Test_Output_Data));
                      memcpy(Test_Output_Data, Test_Input_Data, 48);
                
                      Count_Input_Data = Len_Input_Data -48 -3; //minus Data before payload, 3 bytes of '|' and CRC
                      Counter_Input_Data = 0;
                      while(Counter_Input_Data < Count_Input_Data)
                      {
                            Temp_Byte_Count = Count_Input_Data- Counter_Input_Data;
                            if(Temp_Byte_Count > 8)
                                  Temp_Byte_Count = 8;
                            
                            memcpy(Temp_Input_Frame, &Test_Input_Data[48+Counter_Input_Data], Temp_Byte_Count);
                            //succeeding bytes to be 0
                            if(Temp_Byte_Count < 8)
                            {
                                  memset(&Temp_Input_Frame[Temp_Byte_Count], '0', (8-Temp_Byte_Count));
                                  
                            }
                
                            Display_Data("InPut Data Before Init",Temp_Input_Frame, Temp_Byte_Count);
                
                            //============Initialize the data
                            Temp_Dst_Ptr = (unsigned char *)Temp_Input_Frame;
                            Temp_Src_Ptr = (unsigned char *)&Init_Vector[0];
                            for(Counter_Init_Vector =0;Counter_Init_Vector < 8; Counter_Init_Vector++)
                                   *Temp_Dst_Ptr++ ^= *Temp_Src_Ptr++;
                            //============Initializing data ends
                
                            DES(DESE, (unsigned char *)&Test_Key_Arr[0], 
                                  (unsigned char *)&Temp_Input_Frame[0], (unsigned char *)&Temp_Output_Frame[0]);
                            //DES(TDES3KE, (unsigned char *)&Test_Key_Arr[0], 
                            //    (unsigned char *)&Temp_Input_Frame[0], (unsigned char *)&Temp_Output_Frame[0]);
                            Display_Data("AFTER DES::::", Temp_Output_Frame, Temp_Byte_Count);
                      
                            memcpy(&Test_Output_Data[48+Counter_Input_Data], Temp_Output_Frame, Temp_Byte_Count);
                            Counter_Input_Data += Temp_Byte_Count;
                
                            if(Counter_Input_Data < Count_Input_Data)
                            {
                                  memcpy(Init_Vector, Temp_Output_Frame, 8);
                                  
                            }
                      }
                      
                      {
                            memset(Test_Input_Data, '\0', Len_Input_Data);
                            memcpy(&Test_Input_Data[0], &Test_Output_Data[48], Counter_Input_Data); //1 Separator + 2 CRCs
                      }
                      Display_Data("Final Output Frame", Test_Input_Data, Counter_Input_Data);
                      return Counter_Input_Data;
                }
                do i need to decode the code at my side?

                Edited by: sabre150 on May 3, 2012 8:59 AM

                Moderator action : once again I have added [code ] tags to make the code readable.
                • 5. Re: decryption and padding in java cryptography
                  EJP
                  Actually you need to get rid of both byteToAscii() and stringToHex() altogether. The 'C' code is just sending the ciphertext, you are receiving it in the byte[] buffer, you should be decoding that directly instead of transforming it two or three times.
                  • 6. Re: decryption and padding in java cryptography
                    sabre150
                    Cross posted http://stackoverflow.com/questions/10427205/javax-crypto-badpaddingexceptiongiven-final-block-not-properly-padded

                    Points to note -

                    1) The C code does not encode either as Base64 or Hex.
                    2) The C code does not use PKCS5 padding, it pads with bytes of of the character '0' ('0' and not '\0').
                    3) The ciphertext seems to have the unencrypted 48 byte header so you would seem to need to remove that before decryption.
                    4) Your Java key bytes do not match the C key bytes.


                    The C code does seem to use DESede with CBC mode using an IV of all zeros but you will need to decrypt using 'NoPadding' and then remove the padding bytes yourself. Presumably the 48 byte header has information that will allow the unambiguous removal of the padding bytes.
                    • 7. Re: decryption and padding in java cryptography
                      934529
                      can you tell me after seeing this c code at client end that what should i do to decrypt this hex string at my side. c code is not in my hand. pl post an example to decrypt this frame.
                      • 8. Re: decryption and padding in java cryptography
                        934529
                        yes you r right. i have removed unencrypted text already.
                        41ed34a41a9de6d270aa1e1464527e88c8bee66a00cfb308f60c105de81db0f1ce43d8c0b9bc4e8070b5ab8d4d3650b55d23223fc687bb1485945bc3228e9707a7aecda9f90657e0ac009571c6469c58a2cd9793cc433ccb5993f2
                        is the encrypted part only.
                        • 9. Re: decryption and padding in java cryptography
                          sabre150
                          Please note the edits to my previous reply.
                          • 10. Re: decryption and padding in java cryptography
                            sabre150
                            931526 wrote:
                            can you tell me after seeing this c code at client end that what should i do to decrypt this hex string at my side. c code is not in my hand. pl post an example to decrypt this frame.
                            This site does not provide a free coding service. Even if I was willing to provide code then since I do not know what the cleartext was that produced that ciphertext I cannot sensibly test any code.

                            If you update your Java code according to my suggestions, create an SSCCE ( http://sscce.org/ )that I can run and provide the cleartext associated with the ciphertext I will run the code and check it out.