由于字节数组过长而导致BadPaddingException异常

huangapple go评论79阅读模式
英文:

Getting BadPaddingException due to byte[] too long to decipher

问题

以下是您要翻译的代码部分:

以下代码经过短字符串测试,如果是短字符串,它可以很好地解密字符串。

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); //成功解密字符串
System.out.println("decryptedtext: " + decryptedtext);
[...]
} catch (BadPaddingException e) {
    e.printStackTrace();
}

如果需要进一步的帮助,请随时提问。

英文:

The following code is tested for short strings, in that case it decrypts the string nicely.

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

But if the string is too large I get fired the exception I mention.

What could I do so it decrypts the string correctly maintaining the same large string to decrypt?

Edit, well technically what's decrypted is a byte[], changing title and adding code to not cause possible confussion.

答案1

得分: 2

由于您没有显示加密方式,我们也不知道您使用了什么类型的密钥,因此导致失败的可能原因有很多。此外,您还没有显示导入的部分,因此我无法确定正在使用哪种Base64编码器。

以下是一个简单的程序,对比您要使用的大小要大得多的字节数组进行加密和解密操作。

编辑:
安全警告:下面的代码使用字符串化密钥和静态IV,对一个巨大的字节数组进行单部分加密/解密操作,使用较旧的CBC模式。

请不要复制下面的代码或在生产中使用它 - 仅供教育目的使用。

该代码没有适当的异常处理!

它生成一个(随机填充的)字节数组,其中包含明文,并从转换为byte[]的字符串中获取密钥和IV,使用标准字符集“UTF-8”。

然后,它进行加密,将密文转换为Base64编码的字符串,然后解码为新的密文字节数组,并使用相同的密钥和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); // 生成一个随机填充的字节数组

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

请注意,这段代码存在安全风险,仅供教育目的使用。确保检查任何可能遗漏的字符集设置,并正确(即相同地)使用密钥和IV。

英文:

As you did not show the encryption and we do not know what kind of key you are using there are many possible reasons for failure. As well you did not show the imports so I could just argue what Base64-encoder is in use.

Below you find a simple program that does the en- and decryption a byte array that is much larger than the size you are using.

Edit:
Security warning: The code below uses a stringified key and static IV, uses single part encryption / decryption for a huge byte array, uses the older CBC mode.

Please do not copy below code or use it in production - it is for educational purposes only.

The code does not have any proper exception handling !

It generates a (random filled) byte array with the plaintext and gets the key & iv from strings that are converted to byte[] using the Standard.Charset "UFT-8".

That it's doing the encryption, convert the ciphertext to a Base64 encoded string followed by the decoding to a new ciphertext byte[] and decryption with the same key and iv.

In the end there is simple comparison of the plaintext and decryptedtext byte arrays.

My advice it is to check for any forgotten charset-setting and correct (means identical) usage of key and iv.

code:

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

huangapple
  • 本文由 发表于 2020年7月29日 05:26:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/63143007.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定