2010-07-06 78 views
-3

這是使用AES算法對java中的字符串進行加密和解密的代碼。AES算法中的空指針異常

堆棧跟蹤:

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) 

代碼:

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); 
} 

}`

+0

你可以請包括異常堆棧跟蹤? – bragboy 2010-07-06 04:09:41

+6

可能重複(由相同的用戶):http://stackoverflow.com/questions/3180878/exception-in-aes-decryption-algorithm-in-java,http://stackoverflow.com/questions/3181535/exception-in -aes-decryption-algorithm-in-java – 2010-07-06 04:18:15

+0

我在前面的帖子中提出了修改建議,並且我得到了不同的例外。 – sparkle 2010-07-06 04:23:24

回答

2

的問題是,你的構造是不是一個真正的構造函數,所以skeycipher和其他私有成員從未初始化。

構造函數沒有返回類型定義,因此您需要將public void AES()更改爲public AES


好的,顯然你解決了這個問題。接下來是cipher.init不需要SecretKey,它需要SecretKeySpec。從this example I found工作,你需要這樣的東西:

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

...然後你可以通過skeySpec,你目前正在傳遞skeycipher.init


起,我想,除非我錯計數您的問題與該行:

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

如果驗證cipher不爲空,在這條線的地方,可能拋出NullPointerException正在致電getParameters()或致電getParameterSpec()之後。您可以通過將其分爲多行並檢查堆棧跟蹤(應查看堆棧跟蹤並確定實際拋出異常的位置),輕鬆確定哪些調用引發了異常拋出。

如果我必須賭它,我猜想cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");是無效的。我懷疑這會工作好,如果你有

cipher = Cipher.getInstance("AES"); 
+0

但是,如果我使用Cipher.getInstance(「 AES「),那麼它會拋出Bad Padding Exception。 我按照我以前的文章中的用戶建議,將它改爲CSB模式。 – sparkle 2010-07-06 05:07:39

+0

@ user372066您是否確定了NPE實際發生的位置? – 2010-07-06 05:11:26

+0

其發生在 IvParameterSpec ivspec = param.getParameterSpec(IvParameterSpec.class); – sparkle 2010-07-06 05:14:55