例如。这里javax.crypto.BadPaddingException: Given final block not properly padded error while decryption或Given final block not properly padded
我想加密然后解密字符串。阅读很多主题 “鉴于最终块没有正确填充”例外,但这些解决方案都没有。
我的班级:
package aes;
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.swing.JOptionPane;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
public class EncryptionExample {
private static SecretKeySpec key;
private static IvParameterSpec ivSpec;
private static Cipher cipher;
private static byte[] keyBytes;
private static byte[] ivBytes;
private static int enc_len;
public static void generateKey() throws Exception
{
String complex = new String ("9#82jdkeo!2DcASg");
keyBytes = complex.getBytes();
key = new SecretKeySpec(keyBytes, "AES");
complex = new String("@o9kjbhylK8(kJh7"); //just some randoms, for now
ivBytes = complex.getBytes();
ivSpec = new IvParameterSpec(ivBytes);
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
}
public static String encrypt(String packet) throws Exception
{
byte[] packet2 = packet.getBytes();
cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
byte[] encrypted = new byte[cipher.getOutputSize(packet2.length)];
enc_len = cipher.update(packet2, 0, packet2.length, encrypted, 0);
enc_len += cipher.doFinal(encrypted, enc_len);
return packet = new String(encrypted);
}
public static String decrypt(String packet) throws Exception
{
byte[] packet2 = packet.getBytes();
cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
byte[] decrypted = new byte[cipher.getOutputSize(enc_len)];
int dec_len = cipher.update(packet2, 0, enc_len, decrypted, 0);
HERE EXCEPTION>>>>> dec_len += cipher.doFinal(decrypted, dec_len); <<<<<<<<<
return packet = new String(decrypted);
}
// and display the results
public static void main (String[] args) throws Exception
{
// get the text to encrypt
generateKey();
String inputText = JOptionPane.showInputDialog("Input your message: ");
String encrypted = encrypt(inputText);
String decrypted = decrypt(encrypted);
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
"Encrypted: " + new String(encrypted) + "\n"
+ "Decrypted: : " + new String(decrypted));
.exit(0);
}
}
问题是,当我解密字符串(约4/10个镜头)时,我得到了例外:
Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:966)
at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:479)
at javax.crypto.Cipher.doFinal(Cipher.java:2068)
at aes.EncryptionExample.deszyfrujBez(EncryptionExample.java:HERE tag)
at aes.EncryptionExample.main(EncryptionExample.java:Main starting)
有人知道在这里要改变什么(关键?* .doFinal()方法?)才能使它有效?
@对于那些好奇的人 - 方法必须是静态的,因为这是更大的一部分;)
答案 0 :(得分:4)
当您使用byte[] packet2 = packet.getBytes()
时,您正在根据默认编码转换字符串,例如,可以是UTF-8。没关系。但是你将密文转换回这样的字符串:return packet = new String(encrypted)
如果以后在另一个byte[] packet2 = packet.getBytes()
的decrypt()中没有往返同一个字节数组,这会让你遇到麻烦。
请改为:return packet = new String(encrypted, "ISO-8859-1")
和byte[] packet2 = packet.getBytes("ISO-8859-1")
- 它不是我想要的,但它应该对字节数组进行往返。
答案 1 :(得分:0)
加密的结果是二进制数据。在大多数情况下,它不能被解释为有效的字符串编码。因此,对new String(encrypted)
的调用很可能会扭曲加密的字节,并且在执行packet.getBytes()
之后,您最终会得到一个具有不同内容的字节数组。
解密现在失败,因为密码文本已被更改。填充字节未正确恢复,无法删除。
要解决此问题,请不要将密码文本转换为字符串,并保留字节数组。