0

I know that this question has been asked a couple of times before and I have reviewed the answers to no avail, but what I did get from the answers is that my problem maybe a 'wrong key' issue. This is my first time attempting encryption I put this AES class together from a couple of tutorials I found online. My guess is I have either left something out or have something in the wrong order. Below is my code and the StackTrace. Any help that would point me in the right direction would be much appreciated.

public class AES {

private static ArrayList<String> uncryptedArrayList = new ArrayList<>();
private static String pinString;

private SecretKeyFactory factory;
private KeySpec spec;
private SecretKey tmp;
private Cipher dcipher;
private byte[] salt, iv, decodedData, decryptedData, pin, pass, encryptedData, encodedData;
private int iterationCount = 1024;
private int keyStrength = 128;
private SecretKey key;
private String magic;
private AlgorithmParameters params;

public AES() {

    try {

        salt = new String("TheBestSaltEvers").getBytes();
        magic = new String("ABCDEFGHIJKLMNOP");
        factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        spec = new PBEKeySpec(magic.toCharArray(), salt, iterationCount, keyStrength);
        tmp = factory.generateSecret(spec);
        key = new SecretKeySpec(tmp.getEncoded(), "AES");
        dcipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        params = dcipher.getParameters();
        iv = params.getParameterSpec(IvParameterSpec.class).getIV();

    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (InvalidKeySpecException e) {
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        e.printStackTrace();
    } catch (InvalidParameterSpecException e) {
        e.printStackTrace();
    }
}

public byte[] encrypt(String data) {

    try {

        dcipher.init(Cipher.ENCRYPT_MODE, key);
        encryptedData = dcipher.doFinal(data.getBytes("UTF8"));
        encodedData = new Base64().encode(encryptedData);

    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
        e.printStackTrace();
    } catch (BadPaddingException e) {
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }

    return encodedData;
}

public String decrypt(byte[] data) {

    String result = null;

    try {

        dcipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
        decodedData = new Base64().decode(data);
        decryptedData = dcipher.doFinal(decodedData);

        result = new String(decryptedData, "UTF8");

    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (InvalidAlgorithmParameterException e) {
        e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
        e.printStackTrace();
    } catch (BadPaddingException e) {
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }

    return result;
}

StackTrace

javax.crypto.BadPaddingException: Given final block not properly padded
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:966)
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:824)
    at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:436)
    at javax.crypto.Cipher.doFinal(Cipher.java:2165)
    at security.AES.decrypt(AES.java:108)
    at security.AES.decryptedPinPass(AES.java:187)
    at gui.UserLogin.<init>(UserLogin.java:95)
    at gui.Login.lambda$2(Login.java:191)
    at gui.Login$$Lambda$19/1960756374.run(Unknown Source)
    at java.awt.event.InvocationEvent.dispatch(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$500(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)
javax.crypto.BadPaddingException: Given final block not properly padded
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:966)
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:824)
    at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:436)
    at javax.crypto.Cipher.doFinal(Cipher.java:2165)
    at security.AES.decrypt(AES.java:108)
    at security.AES.decryptedPinPass(AES.java:188)
    at gui.UserLogin.<init>(UserLogin.java:95)
    at gui.Login.lambda$2(Login.java:191)
    at gui.Login$$Lambda$19/1960756374.run(Unknown Source)
    at java.awt.event.InvocationEvent.dispatch(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$500(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)
Dieseled UP
  • 142
  • 1
  • 14

1 Answers1

2

You are forgetting to include the IV in the Cipher.init during encryption. The IV will therefore differ, giving you this error for smaller ciphertext. Usually the IV is prefixed to the ciphertext.

Note that putting everything in fields is really not the way to go. In the end the encrypt and decrypt methods should work independently of each other.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • Thank you added the IV and also changed it to a solid byte[] this fixed the problem. Will also fix the methods on your advice. – Dieseled UP Mar 30 '15 at 00:14
  • The IV should be randomly generated during encrypt and then send to the decrypt method. A static IV goes against everything that an IV should do. – Maarten Bodewes Mar 30 '15 at 00:15
  • Thanks again will fix this, and thanks again, as you have probably guessed am a student so just getting my head around a lot of this. So I appreciate somebody taking their time out to help. – Dieseled UP Mar 30 '15 at 00:38
  • You're welcome. With crypto it is important to note that getting it running is often not the problem. The trick is to get it secure. For instance, just CBC over a network is vulnerable to padding oracle attacks, possible bringing down the security to (almost) zero. – Maarten Bodewes Mar 30 '15 at 00:41
  • Cheers will keep this in mind as I get further into it. – Dieseled UP Mar 30 '15 at 00:55