简体   繁体   English

如何使用BouncyCastle Lightweight API使用PBE AES加密/解密文件?

[英]How to encrypt/decrypt files with PBE AES using BouncyCastle Lightweight API?

I'm trying to encrypt/decrypt files with PBE using AES. 我正在尝试使用AES使用PBE加密/解密文件。 I'm using Bouncy Casle library(lightweight API), because I need to ignoring restrictions on key length. 我正在使用Bouncy Casle库(轻量级API),因为我需要忽略对密钥长度的限制。 I found function and changed some code in it. 我找到了功能并更改了其中的一些代码。

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

}

And I have an error: 我有一个错误:

org.bouncycastle.crypto.InvalidCipherTextException: pad block corrupted org.bouncycastle.crypto.InvalidCipherTextException:填充块已损坏
at org.bouncycastle.crypto.paddings.PKCS7Padding.padCount(Unknown Source) 在org.bouncycastle.crypto.paddings.PKCS7Padding.padCount(未知来源)
at org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher.doFinal(Unknown Source) 在org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher.doFinal(未知来源)

What can I do to remove this error? 我该怎么办才能消除此错误? And what I must to change in this function to get ability to encrypt files. 而且我必须对此功能进行更改才能获得加密文件的功能。

Finally, I found problem, I don't have initialized aesCipher. 最后,我发现了问题,我还没有初始化aesCipher。 When I added method aesCipher.init(true, aesCBCParams); it started working. 当我添加方法aesCipher.init(true, aesCBCParams); it started working. aesCipher.init(true, aesCBCParams); it started working.

And also I changed some code: 我也更改了一些代码:

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

You have a problem with your padding. 您的填充有问题。 This may mean that the incoming cyphertext was encrypted with a different padding, not PKCS7. 这可能意味着传入的密文是使用不同的填充而不是PKCS7加密的。 It may mean that the incoming cyphertext was encrypted in a different mode (not CBC). 这可能意味着传入的密文以不同的模式(不是CBC)进行了加密。 It may mean that you have the wrong key, so the last block decrypts as random. 这可能意味着您使用了错误的密钥,因此最后一个块被随机解密。 If your message is only one block long then it may mean you have a faulty IV, so again the padding is corrupt. 如果您的消息只有一个块长,则可能意味着您的IV错误,因此填充已损坏。

You need to check that the key, mode, padding and IV are identical at both ends. 您需要检查两端的键,模式,填充和IV是否相同。 This means checking key and IV byte by byte. 这意味着逐字节检查密钥和IV。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM