首页 > 解决方案 > 由于 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();
}

但是如果字符串太大,我会因为我提到的异常而被解雇。

我该怎么做才能正确解密字符串并保持相同的大字符串进行解密?

编辑,从技术上讲,解密的是一个字节[],更改标题并添加代码以免引起混淆。

标签: javaencryption

解决方案


由于您没有显示加密并且我们不知道您使用的是哪种密钥,因此失败的可能原因有很多。您也没有显示导入,所以我只能争论使用的是什么 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));
    }
}

推荐阅读