java - 解密加密流时出现 BadPaddingException

标签 java aes javax.crypto

我正在使用 javax.crypto.Cipher 加密文件,然后解密它,但我仍然收到 BadPaddingException。以下类接收来自输入文件的 inputStream 和来自输出文件的 outputStream

错误

13:22:15,049 ERROR [STDERR] javax.crypto.BadPaddingException: Given final block not properly padded
13:22:15,081 ERROR [STDERR]     at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
13:22:15,096 ERROR [STDERR]     at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
13:22:15,128 ERROR [STDERR]     at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
13:22:15,143 ERROR [STDERR]     at javax.crypto.Cipher.doFinal(DashoA13*..)

代码

public class CipherAES implements Cipher {

    private static final Logger logger = Logger.getLogger(CipherAES.class);

    private Key key;

    public CipherAES() {
        this.key = generateKey();
    }

    private Key generateKey() {
        try {
            KeyGenerator generator;
            generator = KeyGenerator.getInstance("AES");
            generator.init(new SecureRandom());
            return generator.generateKey();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public void decrypt(InputStream inputStream, OutputStream outputStream) throws IOException {
        try {
            javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("AES");
            cipher.init(javax.crypto.Cipher.DECRYPT_MODE, key);
            byte[] raw = IOUtil.toByteArray(inputStream);
            byte[] base64Decoded = Base64.decodeBase64(raw);
            byte[] decryptedData = cipher.doFinal(base64Decoded);
            outputStream.write(decryptedData);
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } finally {
            inputStream.close();
            outputStream.close();
        }
    }

    @Override
    public void encrypt(InputStream inputStream, OutputStream outputStream) throws IOException {
        try {
            javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("AES");
            cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, key);
            byte[] raw = IOUtil.toByteArray(inputStream);
            byte[] encryptedData = cipher.doFinal(raw);
            byte[] base64Encoded = Base64.encodeBase64(encryptedData);
            outputStream.write(base64Encoded);
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } finally {
            inputStream.close();
            outputStream.close();
        }
    }

}

日志

# this is log from encryption
raw: 
    [97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122]
encrypted: 
    [92, -104, -48, -10, 95, -3, -21, 46, 27, -60, -115, 85, 114, -95, -126, 108, 88, -105, 94, -84, 86, 86, -75, -83, -73, 24, -109, 86, -34, 83, -35, 106]
base64Encoded: 
    [88, 74, 106, 81, 57, 108, 47, 57, 54, 121, 52, 98, 120, 73, 49, 86, 99, 113, 71, 67, 98, 70, 105, 88, 88, 113, 120, 87, 86, 114, 87, 116, 116, 120, 105, 84, 86, 116, 53, 84, 51, 87, 111, 61]

# this is from decryption
raw (this is the base64Encoded): 
    [88, 74, 106, 81, 57, 108, 47, 57, 54, 121, 52, 98, 120, 73, 49, 86, 99, 113, 71, 67, 98, 70, 105, 88, 88, 113, 120, 87, 86, 114, 87, 116, 116, 120, 105, 84, 86, 116, 53, 84, 51, 87, 111, 61]
base64Decoded (this is the encrypted): 
    [92, -104, -48, -10, 95, -3, -21, 46, 27, -60, -115, 85, 114, -95, -126, 108, 88, -105, 94, -84, 86, 86, -75, -83, -73, 24, -109, 86, -34, 83, -35, 106]
decrypted (this should be the raw from the encryption): 
    I don't know - the exception is thrown 

最佳答案

嗯,你的加密代码一开始似乎有点不稳定:

byte[] raw = IOUtil.toByteArray(inputStream);
byte[] encryptedData = cipher.doFinal();

密码提供要加密的数据怎么样?我怀疑您打算将 raw 传递给 doFinal 调用。

我怀疑这就是完整的问题,但它至少是一个起点。

为后代进行编辑:从评论来看,问题是使用不同的实例进行加密和解密,因此使用不同的 key 。

关于java - 解密加密流时出现 BadPaddingException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7753438/

相关文章:

java - 重启android studio时出现多个java.exe

Java:查找字母出现的最大次数

java - 解密(RSA)字符串的长度正在改变

java - Android - 实现加密 IM 的最佳方式

java - 如何导出对称加密 key ?

java - javax.crypto 编码的字符串在 python 中的河豚解密

jsp - 使用javax.crypto软件包的WSO2应用程序服务器5.0.1 JSP无法编译

java - 在 Spring 中使用 JAX-WS 对 Web 服务客户端进行摘要式密码身份验证

java - 在java中读取和写入文本文件

android - AES 加密数据库条目大小