palAlaa palAlaa - 5 months ago 12
Java Question

javax.crypto.BadPaddingException

I am working on AES algorithm, and I have this exception which I couldn't solve.

javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)


the exception happens in the decryption part.
I initialize the key in a different place from where the decryption algorithm is

KeyGenerator kgen = KeyGenerator.getInstance("AES");//key generation for AES
kgen.init(128); // 192 and 256 bits may not be available


then I pass it with the cipher text which I read from file to the following method

public String decrypt(String message, SecretKey skey) {

byte[] raw = skey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
// Instantiate the cipher
Cipher cipher;

byte[] original = null;
try {
cipher = Cipher.getInstance("AES");

cipher.init(Cipher.DECRYPT_MODE, skeySpec);
System.out.println("Original string: "
+ message);
original = cipher.doFinal(message.trim().getBytes()); //here where I got the exception
String originalString = new String(original);
}
//catches


EDIT
here's the encryption method.

public String encrypt(String message, SecretKey skey) {
byte[] raw = skey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");

// Instantiate the cipher

Cipher cipher;
byte[] encrypted = null;
try {
cipher = Cipher.getInstance("AES");

cipher.init(Cipher.ENCRYPT_MODE, skeySpec);

encrypted = cipher.doFinal(message.getBytes());
System.out.println("raw is " + encrypted);

} catches
return asHex(encrypted);
}


and here's the asHex method

public static String asHex(byte buf[]) {
StringBuffer strbuf = new StringBuffer(buf.length * 2);
int i;

for (i = 0; i < buf.length; i++) {
if (((int) buf[i] & 0xff) < 0x10) {
strbuf.append("0");
}

strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
}

return strbuf.toString();
}


Here's where I read the cipher text form the file

static public String readFile(String filePath) {
StringBuilder file = new StringBuilder();
String line = null;
try {
FileReader reader = new FileReader(filePath);
BufferedReader br = new BufferedReader(reader);
if (br != null) {
line = br.readLine();
while (line != null) {
file.append(line);
// System.out.println("line is " + line);
line = br.readLine();

}
}
br.close();
reader.close();
} catch (IOException ex) {
Logger.getLogger(FileManagement.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("line is " + file.toString());
return String.valueOf(file);

}


can someone help?

Answer

Ok, so the problem is that you are converting the encrypted bytes to a hex string (using the asHex method) but are not converting the hex string back to a byte array correctly for decryption. You can't use getBytes.

You can use the following method to convert a hex string to a byte array:

public static byte[] fromHexString(String s) {
    int len = s.length();
    byte[] data = new byte[len / 2];
    for (int i = 0; i < len; i += 2) {
        data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                             + Character.digit(s.charAt(i+1), 16));
    }
    return data;
}

and then change your decrypt method to use:

original = cipher.doFinal(fromHexString(message));