AES 加密尝试失败 - 给定的最终块可能未正确填充

AES encryption attempt fails - Given final block not properly padded maybe

我知道这个问题之前已经被问过几次了,我已经查看了答案但无济于事,但我从答案中得到的是我的问题可能是 'wrong key' 问题。这是我第一次尝试加密,我将这个 AES class 从我在网上找到的几个教程放在一起。我的猜测是我遗漏了一些东西或者顺序错误。下面是我的代码和 StackTrace。任何能为我指明正确方向的帮助将不胜感激。

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

堆栈跟踪

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(Login.java:191)
    at gui.Login$$Lambda/1960756374.run(Unknown Source)
    at java.awt.event.InvocationEvent.dispatch(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access0(Unknown Source)
    at java.awt.EventQueue.run(Unknown Source)
    at java.awt.EventQueue.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain.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(Login.java:191)
    at gui.Login$$Lambda/1960756374.run(Unknown Source)
    at java.awt.event.InvocationEvent.dispatch(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access0(Unknown Source)
    at java.awt.EventQueue.run(Unknown Source)
    at java.awt.EventQueue.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain.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)

您忘记在加密期间将 IV 包含在 Cipher.init 中。因此 IV 会有所不同,对于较小的密文会出现此错误。通常IV作为密文的前缀。

请注意,将所有内容都放在字段中确实不是可行的方法。最后,加密和解密方法应该相互独立。