当前位置: 首页 > 知识库问答 >
问题:

AndroidAES解密文件:BadPaddingException:EVP\u CipherFinal\u ex

贲凌
2023-03-14

我最近正在研究文件加密/解密。

当我尝试用相同的密钥解密文件时,总是会发生EVP_CipherFinal_ex。

代码片段将在下面发布。

我做错什么了吗?

谢谢你的帮助。

加密

public static void encryptFile() {
    File file = new File(Environment.getExternalStorageDirectory().getPath() + "/" + TARGET_FILE);

    FileInputStream fileInputStream;
    FileOutputStream fileOutputStream;

    byte[] buffer = new byte[1024 * 8];

    IvParameterSpec ivParameterSpec = new IvParameterSpec("1234567890123456".getBytes());

    byte[] key = "only for testing".getBytes();
    MessageDigest sha;
    try {
        sha = MessageDigest.getInstance("SHA-1");
        key = sha.digest(key);
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    key = Arrays.copyOf(key, 16); // use only first 128 bit

    SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");

    try {
        fileInputStream = new FileInputStream(file);
        fileOutputStream = new FileOutputStream(Environment.getExternalStorageDirectory().getPath() + "/" + ENCRYPT_FILE);

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);

        //CipherOutputStream cipherOutputStream = new CipherOutputStream(fileOutputStream, cipher);

        int read;

        while ((read = fileInputStream.read(buffer)) > 0) {
            Log.i(TAG, "encrypt read= " + read);

            byte[] encryptedData = cipher.doFinal(buffer);
            if (encryptedData != null) {
                Log.i(TAG, "encrypted size= " + encryptedData.length);
                fileOutputStream.write(encryptedData, 0, read);
            }

            //cipherOutputStream.write(buffer, 0, buffer.length);
        }
        //cipherOutputStream.flush();
        //cipherOutputStream.close();
        fileInputStream.close();
        fileOutputStream.close();

    } catch (IOException | NoSuchAlgorithmException | NoSuchPaddingException
            | IllegalBlockSizeException | BadPaddingException
            | InvalidAlgorithmParameterException | InvalidKeyException e) {
        e.printStackTrace();
    }
}

解密

public static void decryptFile() {
    File file = new File(Environment.getExternalStorageDirectory().getPath() + "/" + ENCRYPT_FILE);

    FileInputStream fileInputStream;
    FileOutputStream fileOutputStream;

    byte[] buffer = new byte[1024 * 8];

    IvParameterSpec ivParameterSpec = new IvParameterSpec("1234567890123456".getBytes());

    byte[] key = "only for testing".getBytes();
    MessageDigest sha;
    try {
        sha = MessageDigest.getInstance("SHA-1");
        key = sha.digest(key);
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    key = Arrays.copyOf(key, 16); // use only first 128 bit

    SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");

    try {
        fileInputStream = new FileInputStream(file);
        fileOutputStream = new FileOutputStream(Environment.getExternalStorageDirectory().getPath() + "/" + DECRYPT_FILE);

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);

        //CipherInputStream cipherInputStream = new CipherInputStream(fileInputStream, cipher);

        int read;

        while ((read = fileInputStream.read(buffer)) > 0) {
            Log.i(TAG, "decrypt read= " + read);

            byte[] decryptedData = cipher.doFinal(buffer);
            if (decryptedData != null) {
                Log.i(TAG, "decrypted size= " + decryptedData.length);
                fileOutputStream.write(decryptedData, 0, read);
            }

            //fileOutputStream.write(buffer, 0, buffer.length);
        }
        fileOutputStream.flush();
        fileOutputStream.close();
        //cipherInputStream.close();
        fileInputStream.close();

    } catch (IOException | NoSuchAlgorithmException | NoSuchPaddingException
            | IllegalBlockSizeException | BadPaddingException
            | InvalidAlgorithmParameterException | InvalidKeyException e) {
        e.printStackTrace();
    }
}

顺便说一句:当我使用CipherInputStream/CipherOutStream时,它会正常工作。我想知道是否可以只使用FileInputStream/FileOutputStream?非常感谢。

编辑:加密功能将扩大字节数组约16字节,我已尝试增加解密的缓冲区大小,但仍然无法使其工作。

byte[] buffer = new byte[1024 * 8 + 16];

日志:

I/#_:解密读取=8208

javax。加密。BadPaddingException:执行副总裁

在com.Android组织。康斯克里特。NativeCrypto。执行副总裁(本地方法)

在com.android.org.conscrypt.OpenSSLCipher.doFinal内部(OpenSSLCipher.java:430)

com.android.org.conscrypt.OpenSSLCipher.engineDoLast(OpenSSLCipher.java:466)

在javax。加密。密码doFinal(Cipher.java:1340)

在加密助手。解密文件(CryptoHelper.java:128)

根据#Robert的答案编辑了这里的更新代码,适用于遇到与我相同问题的任何人。

加密:

int read;

        while ((read = fileInputStream.read(buffer)) > 0) {
            Log.i(TAG, "encrypt read= " + read);
            byte[] encryptedData = cipher.update(buffer, 0, read);
            //byte[] encryptedData = cipher.doFinal(buffer);
            if (encryptedData != null) {
                Log.i(TAG, "encrypted size= " + encryptedData.length);
                fileOutputStream.write(encryptedData, 0, encryptedData.length);
            }

            //cipherOutputStream.write(buffer, 0, buffer.length);
        }
        byte[] finals = cipher.doFinal();
        Log.i(TAG, "encrypted finals = " + finals.length);
        fileOutputStream.write(finals, 0, finals.length);

解密:

int read;

        while ((read = fileInputStream.read(buffer)) > 0) {
            Log.i(TAG, "decrypt read= " + read);

            //byte[] decryptedData = cipher.doFinal(buffer);
            byte[] decryptedData = cipher.update(buffer, 0, read);
            if (decryptedData != null) {
                Log.i(TAG, "decrypted size= " + decryptedData.length);
                fileOutputStream.write(decryptedData, 0, decryptedData.length);
            }

            //fileOutputStream.write(buffer, 0, buffer.length);
        }
        byte[] finals = cipher.doFinal();
        Log.i(TAG, "decrypted finals = " + finals.length);
        fileOutputStream.write(finals, 0, finals.length);

再次感谢罗伯特的帮助。

共有1个答案

储俊英
2023-03-14

你的问题是,你总是调用cipher.dofint()为每个错误的数据块,因为每个块将被填充。

如果您正在加密/解密数据块,请使用密码。更新(…) 并且在处理最后一个块之后,只调用密码。doFinal()一次。

更简单的方法是使用CipherInputStream/CipherOutputStream——它完全符合我为您描述的内容(关闭流时调用doFinal)。

 类似资料:
  • 问题内容: 嗨,我有1000个加密工作簿,我想通过提供一个密码来解密。我在apache poi或python的xlrd模块下找不到解密方法。 有谁知道可以处理此()的库。我希望我可以从unix框中使用lib。 谢谢 问题答案: 使用COM绑定来调用该方法。 SaveAs可以应用新密码。请参阅:http : //msdn.microsoft.com/zh- cn/library/microsoft.

  • 我不完全确定我该做什么了。我一直在网上到处乱翻东西,通读例子,但它们似乎都是如何加密一整个文件,或者只是加密一段数据,除了立即再次解密之外什么也不做。我该如何处理逐行书写?

  • 问题内容: 下面的加密功能似乎起作用,因为它似乎可以加密文件并将其放置在预期的目录中。我现在正在尝试解密文件,并且它只死于消息“无法完成解密”(在此处进行编码…)。php错误日志中没有任何内容,因此我不确定为什么它会失败,但由于mcrypt对我来说是全新的,所以我更倾向于相信自己在这里做错了… 功能如下: 问题答案: 由于mcrypt是一种废弃软件,不再建议使用,因此这里是使用openssl的示例

  • 我的理解是,公钥可以用于加密,私钥可以用于解密,公钥不能解密由同一公钥加密的文件。我有没有误解,或者我做错了什么? 1) 生成密钥 openssl genrsa-out./private.pem2048 2) 生成公钥 openssl rsa-in/私有的pem-发布 3)加密一个小文本文件 openssl加密/在里面txt-输出/出来附件e-aes256-k/平民的pem公司 4) 使用公钥解密

  • 所以我有这些大文件(6GB+),我需要在32位计算机上解密。我以前使用的一般过程是读取内存中的整个文件,然后将其传递给解密函数,然后将其全部写回一个文件。由于内存限制,这实际上不起作用。我尝试将文件分成几部分传递给decrypt函数,但在将文件发送给decrypt函数之前,它似乎会在分解文件的边界附近搞乱。 以下是我的解密函数/我尝试部分解密。

  • 在本章中,让我们讨论使用Python解密加密文件。 请注意,对于解密过程,我们将遵循相同的过程,但不是指定输出路径,而是关注输入路径或加密的必要文件。 Code 以下是使用Python解密加密文件的示例代码 - #!/usr/bin/python # ---------------- READ ME --------------------------------------------- # T