简体   繁体   中英

Incremental Encryption with BouncyCastle PGP Utilities in Java

I'm trying to write an encrypted file that will be decrypted using gpg and will be writing lines incrementally instead of in one chunk. I've generated the keys in GnuPG and am using the public key to encrypt. Here's the method I'm using to encrypt:

  public static byte[] encrypt(byte[] clearData, PGPPublicKey encKey,
            String fileName,boolean withIntegrityCheck, boolean armor)
            throws IOException, PGPException, NoSuchProviderException {
        if (fileName == null) {
            fileName = PGPLiteralData.CONSOLE;
        }

        ByteArrayOutputStream encOut = new ByteArrayOutputStream();

        OutputStream out = encOut;
        if (armor) {
            out = new ArmoredOutputStream(out);
        }

        ByteArrayOutputStream bOut = new ByteArrayOutputStream();

        PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(
                PGPCompressedDataGenerator.ZIP);
        OutputStream cos = comData.open(bOut); // open it with the final
        // destination
        PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator();

        // we want to generate compressed data. This might be a user option
        // later,
        // in which case we would pass in bOut.
        OutputStream pOut = lData.open(cos, // the compressed output stream
                PGPLiteralData.BINARY, fileName, // "filename" to store
                clearData.length, // length of clear data
                new Date() // current time
                );
        pOut.write(clearData);

        lData.close();
        comData.close();

        PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_192).setSecureRandom(new SecureRandom()));


        cPk.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(encKey));

        byte[] bytes = bOut.toByteArray();

        OutputStream cOut = cPk.open(out, bytes.length);

        cOut.write(bytes); // obtain the actual bytes from the compressed stream

        cOut.close();

        out.close();

        return encOut.toByteArray();
    }

And I have a small prototype test class to use that method like this:

            PGPPublicKey pubKey = PGPEncryptionTools.readPublicKeyFromCol(new FileInputStream(appProp.getKeyFileName()));

        byte[] encryptbytes = PGPEncryptionTools.encrypt("\nthis is some test text".getBytes(), pubKey, null, true, false);
        byte[] encryptbytes2 = PGPEncryptionTools.encrypt("\nmore test text".getBytes(), pubKey, null, true, false);

        FileOutputStream fos = new FileOutputStream("C:/Users/me/workspace/workspace/spring-batch-project/resources/encryptedfile.gpg");
        fos.write(encryptbytes);
        fos.write(encryptbytes2);
        fos.flush();
        fos.close();

So this creates encryptedfile.gpg , but when I go to GnuPG to decrypt the file, it works but it only outputs the first line "this is some test text".

How can I modify this code to be able to encrypt both lines and have GnuPG decrypt them?

You're producing multiple, independent OpenPGP messages each time calling your PGPEncryptionTools.encrypt(...) method. To only output a single OpenPGP message (which GnuPG also decrypt in a single run), write all plain text to a single stream (called pOut in your code) and do not close this before finally writing the last byte into the stream.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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