【问题标题】:How to encrypt/decrypt files with PBE AES using BouncyCastle Lightweight API?如何使用 BouncyCastle Lightweight API 使用 PBE AES 加密/解密文件?
【发布时间】:2011-11-10 11:51:12
【问题描述】:

我正在尝试使用 AES 使用 PBE 加密/解密文件。我正在使用 Bouncy Casle 库(轻量级 API),因为我需要忽略对密钥长度的限制。我找到了函数并更改了其中的一些代码。

public void decryptLW(InputStream in, OutputStream out, String password, byte[] salt, final int iterationCount) throws Exception {

    PKCS12ParametersGenerator pGen = new PKCS12ParametersGenerator(new SHA256Digest());
    char[] passwordChars = password.toCharArray();
    final byte[] pkcs12PasswordBytes = PBEParametersGenerator.PKCS12PasswordToBytes(passwordChars);
    pGen.init(pkcs12PasswordBytes, salt, iterationCount);
    CBCBlockCipher aesCBC = new CBCBlockCipher(new AESEngine());
    ParametersWithIV aesCBCParams = (ParametersWithIV) pGen.generateDerivedParameters(256, 128);
    aesCBC.init(false, aesCBCParams);
    PaddedBufferedBlockCipher aesCipher = new PaddedBufferedBlockCipher(aesCBC, new PKCS7Padding());

    try {

        // Read in the decrypted bytes and write the cleartext to out
        int numRead = 0;
        while ((numRead = in.read(buf)) >= 0) {

            byte[] plainTemp = new byte[aesCipher.getOutputSize(buf.length)];
            int offset = aesCipher.processBytes(buf, 0, buf.length, plainTemp, 0);
            int last = aesCipher.doFinal(plainTemp, offset);
            final byte[] plain = new byte[offset + last];
            System.arraycopy(plainTemp, 0, plain, 0, plain.length);

            out.write(plain, 0, numRead);
        }
        out.close();
        in.close();
    } catch (java.io.IOException e) {
    }

}

我有一个错误:

org.bouncycastle.crypto.InvalidCipherTextException:垫块损坏
在 org.bouncycastle.crypto.paddings.PKCS7Padding.padCount(未知来源)
在 org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher.doFinal(未知来源)

我可以做些什么来消除这个错误?以及我必须在此功能中进行哪些更改才能获得加密文件的能力。

【问题讨论】:

  • 您考虑过使用CipherInputStreamCipherOutputStream 类吗?让你的代码更简单。

标签: java encryption cryptography aes bouncycastle


【解决方案1】:

最后,我发现了问题,我没有初始化 aesCipher。当我添加方法aesCipher.init(true, aesCBCParams); it started working.

我还更改了一些代码:

int numRead = 0;
        while ((numRead = fin.read(buf)) >= 0) {
            if (numRead == 1024) {
                byte[] plainTemp = new byte[aesCipher.getUpdateOutputSize(numRead)];
                int offset = aesCipher.processBytes(buf, 0, numRead, plainTemp, 0);

                final byte[] plain = new byte[offset];
                System.arraycopy(plainTemp, 0, plain, 0, plain.length);
                fout.write(plain, 0, plain.length);
            } else {
                byte[] plainTemp = new byte[aesCipher.getOutputSize(numRead)];
                int offset = aesCipher.processBytes(buf, 0, numRead, plainTemp, 0);
                int last = aesCipher.doFinal(plainTemp, offset);
                final byte[] plain = new byte[offset + last];
                System.arraycopy(plainTemp, 0, plain, 0, plain.length);
                fout.write(plain, 0, plain.length);
            }
        }

【讨论】:

    【解决方案2】:

    您的填充有问题。这可能意味着传入的密文是用不同的填充加密的,而不是 PKCS7。这可能意味着传入的密文以不同的模式(不是 CBC)加密。这可能意味着您的密钥错误,因此最后一个块会随机解密。如果您的消息只有一个块长,则可能意味着您的 IV 有问题,因此填充再次损坏。

    您需要检查两端的键、模式、填充和 IV 是否相同。这意味着逐字节检查密钥和IV。

    【讨论】:

    • 谢谢!也许你可以说我,我必须在这段代码中改变什么来加密文件?
    • @kelheor 在aesCBC.init(false, aesCBCParams); 行中,false 参数表示您正在解密。使用true 进行加密。 Bouncy Castle Javadocs 涵盖了这一点。
    • 现在,我正在尝试加密文件,并且该错误再次返回,在 fucntion aesCipher.doFinal(plainTemp, offset); org.bouncycastle.crypto.InvalidCipherTextException: pad block 在 org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher.doFinal(Unknown Source) 的 org.bouncycastle.crypto.paddings.PKCS7Padding.padCount(Unknown Source) 损坏
    • @kelheor: »pad block损坏«不应该在加密时发生。看起来您正在对明文使用解密功能(这显然会产生问题)。
    猜你喜欢
    • 1970-01-01
    • 2015-08-22
    • 2011-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-23
    • 1970-01-01
    相关资源
    最近更新 更多