java - 由于 byte[] 太长而无法破译而导致 BadPaddingException
问题描述
以下代码针对短字符串进行了测试,在这种情况下,它很好地解密了字符串。
byte[] ciphertext = Base64.decode(myverylongstring,Base64.DEFAULT);
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(Charset.forName("UTF-8")), "AES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(Charset.forName("UTF-8")));
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] decryptedtextByte = cipher.doFinal(ciphertext);
String decryptedtext = new String(decryptedtextByte); //Successfully decrypts the string
System.out.println("decryptedtext: " + decryptedtext);
[...]
} catch (BadPaddingException e) {
e.printStackTrace();
}
但是如果字符串太大,我会因为我提到的异常而被解雇。
我该怎么做才能正确解密字符串并保持相同的大字符串进行解密?
编辑,从技术上讲,解密的是一个字节[],更改标题并添加代码以免引起混淆。
解决方案
由于您没有显示加密并且我们不知道您使用的是哪种密钥,因此失败的可能原因有很多。您也没有显示导入,所以我只能争论使用的是什么 Base64 编码器。
下面是一个简单的程序,它对一个比您使用的大小大得多的字节数组进行加密和解密。
编辑: 安全警告:下面的代码使用字符串化密钥和静态 IV,对大字节数组使用单部分加密/解密,使用较旧的 CBC 模式。
请不要复制以下代码或在生产中使用它 - 它仅用于教育目的。
该代码没有任何适当的异常处理!
它使用纯文本生成一个(随机填充的)字节数组,并从使用 Standard.Charset“UFT-8”转换为 byte[] 的字符串中获取密钥 & iv。
它正在进行加密,将密文转换为 Base64 编码的字符串,然后解码为新的密文字节 [] 并使用相同的密钥和 iv 解密。
最后,对明文和解密文本字节数组进行了简单的比较。
我的建议是检查任何被遗忘的字符集设置并正确(意味着相同)使用 key 和 iv。
代码:
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;
public class Main {
public static void main(String[] args) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
System.out.println("https://stackoverflow.com/questions/63143007/getting-badpaddingexception-due-to-byte-too-long-to-decipher");
byte[] plaintext = new byte[100000];
SecureRandom secureRandom = new SecureRandom();
secureRandom.nextBytes(plaintext); // generate a random filled byte array
byte[] key = "12345678901234567890123456789012".getBytes(StandardCharsets.UTF_8);
byte[] iv = "1234567890123456".getBytes(StandardCharsets.UTF_8);
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] ciphertextEnc = cipher.doFinal(plaintext);
String ciphertextBase64 = Base64.getEncoder().encodeToString(ciphertextEnc);
byte[] ciphertextDec = Base64.getDecoder().decode(ciphertextBase64);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] decryptedtextByte = cipher.doFinal(ciphertextDec);
System.out.println("decryptedtextByte equals plaintext: " + Arrays.equals(plaintext, decryptedtextByte));
}
}
推荐阅读
- vba - 将 VBA“设置”功能从子模块移动到模块
- java - Flutter - Android 许可证状态未知
- c# - C# 虚拟键修饰键使用发送输入法失败
- android - 我的 gradlew.bat 在 tns build android 上一直失败
- javascript - 无法让我的 Google 可视化饼图和表格溢出滚动条工作
- c# - 发送响应后保存到数据库(.NET Core 和 EF Core)
- c# - 如何使用区域短日期将 DateTime 转换为字符串
- r - 从 app.R 中调用 Source_python 时不起作用
- python - 我可以允许 tkinter 的 mainloop() 和 GLUT 的 glutMainLoop() 同时运行吗?
- laravel - Uppy "PUT" XHR(multipart/form-data) 请求结果清空 Laravel $request 数组