-3

This is the code for encrypting and decrypting a string in java using AES algorithm.

StackTrace:

    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 test.AES.AESdecryptalgo(AES.java:76)
    at test.AES.main(AES.java:95)

Code:

package test;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.security.*;

public class AES
{
  public byte[] encrypted;
  public byte[] original;

  public String originalString;
  Cipher cipher;
  SecretKeySpec skeySpec;
  IvParameterSpec spec;
  byte [] iv;
  /*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();
}*/
  public AES()
  {
        try
        {
            KeyGenerator kgen = KeyGenerator.getInstance("AES");
            kgen.init(128);
            SecretKey skey = kgen.generateKey();
            byte[] raw = skey.getEncoded();
            skeySpec = new SecretKeySpec(raw, "AES");
            cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

        }
        catch(Exception ex)
        {ex.printStackTrace();}
  }
public String AESencryptalgo(byte[] text)
{
    String newtext="";
    try
    {
        // byte[] raw = skey.getEncoded();
        //SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
            AlgorithmParameters param = cipher.getParameters();
            IvParameterSpec ivspec=param.getParameterSpec(IvParameterSpec.class);
            iv=ivspec.getIV();
            spec=new IvParameterSpec(iv);
        //AlgorithmParameters params = cipher.getParameters();
        //iv = params.getParameterSpec(IvParameterSpec.class).getIV();
        encrypted = cipher.doFinal(text);

    }
   catch(Exception e)
   {
       e.printStackTrace();
   }
   finally
   {
      newtext=new String(encrypted);
       //System.out.println("ENCRYPTED "+newtext);
       return newtext;
    }
}
public  String AESdecryptalgo(byte[] text)
{
    try
    {

        cipher.init(Cipher.DECRYPT_MODE, skeySpec,spec);
        original = cipher.doFinal(text);   //Exception occurs here
        originalString = new String(original);

    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
    finally
    {

        return originalString;
    }
}
public static void main(String[] args)
{
    AES a=new AES();
    String encrypt=a.AESencryptalgo("hello".getBytes());
    System.out.println(encrypt);
    String decrypt=a.AESdecryptalgo(encrypt.getBytes());
    System.out.println(decrypt);
}

}`

6
  • Can you please include the exception stack trace? Commented Jul 6, 2010 at 4:09
  • 6
    Possible duplicates (by same user): stackoverflow.com/questions/3180878/…, stackoverflow.com/questions/3181535/… Commented Jul 6, 2010 at 4:18
  • I made the modifications suggested in my prev posts and i got different exceptions. Commented Jul 6, 2010 at 4:23
  • 4
    Except you didn't bother to try to understand the other posts. StackOverflow isn't WriteMyCodeForMe.com nor ICanNotBeBotheredToLearnWhatIamDoing.com Commented Jul 6, 2010 at 4:32
  • Your stacktrace no longer seems to match your code. Line 48 of what you've posted couldn't possibly throw an NPE. Please update the stack trace or the code so that they match! Commented Jul 6, 2010 at 4:44

1 Answer 1

2

The problem is that your constructor isn't really a constructor, so skey, cipher and the other private members are never initialized.

Constructors are defined without return types, so you need to change public void AES() to public AES.


Okay, apparently you fixed that problem. The next is that cipher.init doesn't take a SecretKey, it takes a SecretKeySpec. Working from this example I found you need something like:

byte[] raw = skey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");

...and then you can pass skeySpec where you're currently passing skey to cipher.init.


Onwards, I suppose, unless I'm counting wrong your issue is with this line:

 iv = cipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV();

If you verify that cipher is not null, the places on this line that could throw a NullPointerException are after the getParameters() call or after the getParameterSpec() call. You can easily determine which of these calls is causing the exception to be thrown by splitting this into multiple lines and examining the stack trace (you should look at the stack trace and determine where the exception is actually being thrown).

If I had to bet on it I'd guess that cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); isn't valid. I suspect this would work okay if you had

cipher = Cipher.getInstance("AES");
Sign up to request clarification or add additional context in comments.

7 Comments

But if I am using Cipher.getInstance("AES") then it will throw Bad Padding Exception. I changed it ot CSB mode as suggested by a user in my prev post.
@user372066 have you determined where the NPE is actually occurring?
Its occurring at IvParameterSpec ivspec=param.getParameterSpec(IvParameterSpec.class);
@user, then param is null, which means cipher.getParameters() is returning null.
For anyone wondering, the NullPointerException on getParameters() is caused by an Android 4.3.x bug: code.google.com/p/android/issues/detail?id=58191
|

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.