0

I have a problem with with

javax.crypto.Cipher

When I write this lines of code

    Cipher cipher;
    byte[] bytes = null;

    try
    {
        cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, generateAESKey128b(key));
        bytes = cipher.doFinal(input.getBytes("UTF-8"));
    }
    catch (NoSuchAlgorithmException e)
    {
        e.printStackTrace();
    }
    catch (NoSuchPaddingException e)
    {
        e.printStackTrace();
    }
    catch (InvalidKeyException e)
    {
        e.printStackTrace();
    }
    catch (UnsupportedEncodingException e)
    {
        e.printStackTrace();
    }
    catch (IllegalBlockSizeException e)
    {
        e.printStackTrace();
    }
    catch (BadPaddingException e)
    {
        e.printStackTrace();
    }

The console give me this error

javax.crypto.IllegalBlockSizeException 
Input length must be multiple of 16 when    
decrypting with padded cipher
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*..)
at it.unitn.se.gym.backend.utils.Security.AES128Decode(Security.java:109)
at it.unitn.se.gym.backend.utils.Security.decode_AES128_Base64(Security.java:96)
at it.unitn.se.gym.backend.WebService.main(WebService.java:42)
Exception in thread "main" java.lang.NullPointerException
at it.unitn.se.gym.backend.utils.Security.decode_AES128_Base64(Security.java:97)
at it.unitn.se.gym.backend.WebService.main(WebService.java:42)

The first 2 lines of code are correct but when I pass the attribute "text", of type byte[], to the doFinal function, it give me the error.

Can someone tell me why?

SOLVED:

Okay, problem solved

byte[] encrypted = UniversalBase64Encoder.decode(input);
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, generateAESKey128b(key));
byte[] originalBytes = cipher.doFinal(encrypted);

This is the right code that I wrote

David Martinelli
  • 233
  • 6
  • 16

1 Answers1

1

The problem is that you're trying to decrypt a string that was not encrypted, and in doing so are violating an assumption of the decryption algorithm (that its input size is always a multiple of 16).

Here's a block of code that encrypts and then decrypts a string. Notice that when the encrypted string is printed, it's 16 bytes long, even though the input string is not. The encryption algorithm pads the input string out to make it a multiple of 16 bytes before encrypting it. That 16-byte-long encrypted string is now a valid input for decryption.

This assumption (that the result of encrypting will be an even size) is quite standard. It not only makes the decryption/encryption algorithm easier to write, but it also prevents an attacker from knowing the length of the thing you encrypted.

byte[] keyBytes = new byte[16];
keyBytes[0] = 1;
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
String input = "hello";
Cipher cipher;
byte[] bytes = null;
cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, key);
bytes = cipher.doFinal(input.getBytes("UTF-8"));

System.out.println("Encoded: "+Arrays.toString(bytes));

cipher.init(Cipher.DECRYPT_MODE, key);
byte[] decoded = cipher.doFinal(bytes);

System.out.println("Decoded: "+new String(decoded, "UTF-8"));
Nathaniel Waisbrot
  • 23,261
  • 7
  • 71
  • 99
  • 1
    So, if I have an encrypted string (passed from someone), and I have the shared key (key of encryption and decryption), how can I decrypt the string? – David Martinelli Mar 19 '13 at 15:18
  • @DavidMartinelli Like I'm doing in the final 3 lines. If you're getting that error from a string that somebody has told you is encrypted, then one of the following is true (1) it's not actually encrypted (2) it's encrypted using some algorithm other than what you're using (3) you have mangled the encrypted string prior to trying to decrypt it – Nathaniel Waisbrot Mar 19 '13 at 15:31