2010-07-06 4 views
-3

이것은 AES 알고리즘을 사용하여 java에서 문자열을 암호화하고 암호 해독하기위한 코드입니다.Null PointerException 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

+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 –

+0

나는 나의 이전 게시물에서 제안 된 수정을했고 나는 다른 예외를 가지고있다. – sparkle

답변

2

문제는 생성자가 정말 그렇게 skey, cipher 및 기타 개인 회원 생성자되지 않는 것입니다 절대로 초기화되지 않습니다.

생성자는 반환 유형없이 정의되므로 public void AES()public AES으로 변경해야합니다.


좋아요, 문제를 해결 한 것 같습니다. 다음은 cipher.initSecretKey이 아니며, SecretKeySpec이 걸립니다. this example I found에서 작업하기 좋아하는 뭔가가 필요합니다

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

을 ... 그리고 현재 cipher.initskey을 전달하는 경우 당신은 skeySpec를 전달할 수 있습니다.

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

당신이이 cipher가 null는 아니고,이 라인의 장소가 던질 수 있는지 확인하는 경우 : 나는 당신의 문제가이 라인으로되어 잘못된 믿는다 않는 전방으로


, 나는, 가정 NullPointerExceptiongetParameters() 통화 이후 또는 getParameterSpec() 통화 이후입니다. 이 호출을 여러 행으로 분할하고 스택 추적을 검사하여 예외를 발생시키는 호출을 쉽게 결정할 수 있습니다 (은 스택 추적을보고 예외가 실제로 throw되는 위치를 결정해야합니다).

내가 내기를해야한다면 cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");이 유효하지 않다고 생각할 수 있습니다. 당신이 가진다면 괜찮을 것 같아.

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

하지만 Cipher.getInstance (" AES ") 그러면 Bad Padding Exception을 던집니다. 이전 게시물에서 사용자가 제안한대로 CSB 모드로 변경했습니다. – sparkle

+0

@ user372066 NPE가 실제로 어디에서 발생했는지 확인 했습니까? –

+0

발생 위치 : IvParameterSpec ivspec = param.getParameterSpec (IvParameterSpec.class); – sparkle