+
95
-

回答

javax.crypto.BadPaddingException: Given final block not properly padded 是一个常见的异常,通常在使用对称加密算法(如 AES、DES)时出现。这个异常通常表示加密或解密过程中的数据填充有问题。下面是一些可能导致这个异常的常见原因及解决方法:

1. 填充方式不匹配

加密和解密时使用的填充方式必须一致。常见的填充方式包括 PKCS5Padding 和 PKCS7Padding。确保你在加密和解密时使用了相同的填充方式。

示例:

String transformation = "AES/CBC/PKCS5Padding";
Cipher cipher = Cipher.getInstance(transformation);
2. 密钥不匹配

加密和解密时使用的密钥必须一致。如果密钥不匹配,也可能导致这个异常。

3. 数据损坏

加密后的数据在传输或存储过程中可能会被损坏,导致解密时出现填充错误。确保数据在传输和存储过程中保持完整性。

4. 初始向量(IV)不匹配

如果你使用的是带有模式的加密算法(如 CBC 模式),加密和解密时使用的初始向量(IV)必须一致。

5. 解密的数据不是有效的填充格式

尝试解密的数据可能不是使用预期的填充方式加密的。例如,你可能尝试解密一个未加密或使用不同算法加密的数据。

示例代码

下面是一个完整的示例,展示了如何正确地使用 AES 加密和解密,确保填充方式、密钥和 IV 一致。

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import java.security.SecureRandom;
import java.util.Base64;

public class AESExample {
    public static void main(String[] args) throws Exception {
        // Generate a new AES key
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(256); // for example, 128, 192, or 256 bits key
        SecretKey secretKey = keyGen.generateKey();

        // Generate a new IV
        byte[] iv = new byte[16];
        SecureRandom random = new SecureRandom();
        random.nextBytes(iv);
        IvParameterSpec ivSpec = new IvParameterSpec(iv);

        // Example plaintext
        String plaintext = "This is a secret message";

        // Encrypt the plaintext
        Cipher encryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        encryptCipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
        byte[] encryptedBytes = encryptCipher.doFinal(plaintext.getBytes("UTF-8"));
        String encryptedText = Base64.getEncoder().encodeToString(encryptedBytes);
        String ivText = Base64.getEncoder().encodeToString(iv);

        System.out.println("Encrypted: " + encryptedText);
        System.out.println("IV: " + ivText);

        // Decrypt the ciphertext
        Cipher decryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        decryptCipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(Base64.getDecoder().decode(ivText)));
        byte[] decryptedBytes = decryptCipher.doFinal(Base64.getDecoder().decode(encryptedText));
        String decryptedText = new String(decryptedBytes, "UTF-8");

        System.out.println("Decrypted: " + decryptedText);
    }
}
关键点密钥生成和使用一致:确保在加密和解密过程中使用相同的密钥。初始向量(IV)一致:在 CBC 模式下,确保加密和解密使用相同的 IV。填充方式一致:在加密和解密过程中使用相同的填充方式,如 PKCS5Padding。

通过确保以上几点的一致性,可以避免 javax.crypto.BadPaddingException: Given final block not properly padded 异常的发生。

网友回复

我知道答案,我要回答