java2485
java2485

Reputation: 171

padding exception and decryption in java

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.

Upvotes: 0

Views: 2872

Answers (4)

rossum
rossum

Reputation: 15685

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.

Upvotes: 0

ixe013
ixe013

Reputation: 10171

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.

Upvotes: 1

MByD
MByD

Reputation: 137362

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

Upvotes: 0

Mister Smith
Mister Smith

Reputation: 28168

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

Upvotes: 0

Related Questions