Null PointerException in AES algorithm
This is the code for encrypting and de开发者_开发知识库crypting 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);
}
}`
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");
精彩评论