0

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, key, 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.

2
  • This is not right (assuming that function is doing what its name implies): completeHexString = function.stringToHex(byteToAscii);. You don't decode hex, you decode binary. Commented May 2, 2012 at 11:34
  • The way you read from your input stream is wrong. You must use a loop. Commented May 2, 2012 at 11:44

4 Answers 4

1

PKCS5 padding byte value must be the number of padding bytes. For example, if there is 5 bytes to pad, your padding will be 05 05 05 05 05. It there is two bytes to pad, the padding will be 02 02.

Sign up to request clarification or add additional context in comments.

Comments

0

Why don't you just try CipherInputStream and CipherOutputStream? That way you could forget about paddings.

4 Comments

because only a portion of frame is encrypted. rest is a normal hex string.
You can use a ByteArrayInputStream to convert from byte array to stream.
but this is not my problem. when the client send normal hex string(without encryption) then i receive a perfectly fine data. my problem arise only when i receive normal + encrypted( a portion) data. i don't know how to decrypt it correctly or how to pad it with zeros?
Certainly, the input (when decrypting) should have a certain length, depending on the block size. But if the input has been generated as result of a correct encryption, you shouldn't have any problem.
0

temparray[88] means you are accessing the 89th byte, isn't it one too much?

I think you should have only:

temparray[87] = 00; // this is byte number 88

And remove the

temparray[88] = 00; // this is byte number 89

1 Comment

yes you r right. i am just padding temparray[87] = 00; not the 88th. i am correcting my question for this. but still then i m getting exception "Given final block not properly padded".
0

You error message is telling you that there is a problem with the length of the last block: "Input length must be multiple of 8 when decrypting with padded cipher"

Looking at your input frame, its length is not a multiple of 8. I count eleven full 8-byte blocks and one half block of four bytes, for a total of 92 bytes. Should you be stripping out some non-encrypted stuff before attempting to decrypt? Has the full message arrived?

I also notice that at one point you are encoding your buffer as Hex, and at a later point your are decoding it as Base-64. That will probably not give you what you are expecting. It could also account for the length problem. Four characters of hex is two bytes, while four characters of Base-64 is three bytes.

2 Comments

thanx 4 ur reply rossum. i have modified my code. now length is dividable by 8. also 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); --
First decrypt with "NoPadding", which will accept any sort of padding on the last block. Then have a look at the hex of your last block. That will tell you what padding is being used at the encrypting end. Amend your code to expect the correct type of padding.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.