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作为密文的前缀。
请注意,将所有内容都放在字段中确实不是可行的方法。最后,加密和解密方法应该相互独立。
我知道这个问题之前已经被问过几次了,我已经查看了答案但无济于事,但我从答案中得到的是我的问题可能是 '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作为密文的前缀。
请注意,将所有内容都放在字段中确实不是可行的方法。最后,加密和解密方法应该相互独立。