2010-07-06 4 views
-3

Ceci est le code pour crypter et décrypter une chaîne dans Java en utilisant l'algorithme AES.Null PointerException dans l'algorithme AES

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

} `

+0

Pouvez-vous inclure la trace de pile d'exception? – bragboy

+6

Copies possibles (par le même utilisateur): 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

J'ai fait les modifications suggérées dans mes posts précédents et j'ai eu différentes exceptions. – sparkle

Répondre

2

Le problème est que votre constructeur est pas vraiment un constructeur, donc skey, cipher et les autres membres privés ne sont jamais initialisés. Les constructeurs sont définis sans types de retour. Vous devez donc remplacer public void AES() par public AES.


D'accord, vous avez apparemment résolu ce problème. Le suivant est que cipher.init ne prend pas un SecretKey, il prend un SecretKeySpec. Travailler à partir this example I found dont vous avez besoin quelque chose comme:

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

... et vous pouvez passer skeySpec où vous passez actuellement à skeycipher.init.


Onwards, je suppose, à moins que je compte mal votre problème avec cette ligne:

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

Si vous vérifiez que cipher est non nul, les endroits sur cette ligne qui pourrait lancer une NullPointerException sont après l'appel getParameters() ou après l'appel getParameterSpec(). Vous pouvez facilement déterminer lequel de ces appels provoque le rejet de l'exception en le divisant en plusieurs lignes et en examinant la trace de la pile ( doit regarder la trace de la pile et déterminer où l'exception est réellement levée).

Si je devais parier dessus, je devinerais que cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); n'est pas valide. Je suppose que cela fonctionnerait bien si vous aviez

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

Mais si j'utilise Cipher.getInstance (" AES ") alors il va lancer Bad Padding Exception. Je l'ai changé sur le mode CSB comme suggéré par un utilisateur dans mon post précédent. – sparkle

+0

@ user372066 avez-vous déterminé où le NPE se produit réellement? –

+0

Cela se produit à IvParameterSpec ivspec = param.getParameterSpec (IvParameterSpec.class); – sparkle