问题
I'm working on a proof of concept Java application that reads a series of newline-separated requests from a PGP-encrypted file, processes those requests, and then writes the responses to another PGP-encrypted file, with a flush after each response write.
I've successfully integrated Bouncy Castle 1.5 with my application with the exception that I cannot seem to flush the output on command:
private ArmoredOutputStream armoredOut = null;
private OutputStream compressedOut = null;
private OutputStream encryptedOut = null;
public OutputStream encryptStream(OutputStream outputStream){
OutputStream literalOut = null;
try{
armoredOut = new ArmoredOutputStream(outputStream);
BcPGPDataEncryptorBuilder dataEncryptor = new BcPGPDataEncryptorBuilder(PGPEncryptedData.AES_256);
dataEncryptor.setSecureRandom(new SecureRandom());
PGPEncryptedDataGenerator encryptGen = new PGPEncryptedDataGenerator(dataEncryptor);
PGPPublicKey publicKey = null;
InputStream publicKeyStream = null;
try{
publicKeyStream = this.getClass().getClassLoader().getResourceAsStream(keyName);
publicKey = getEncryptionKey(publicKeyStream);
}
finally{
if(publicKeyStream != null){
publicKeyStream.close();
}
}
if(publicKey == null){
throw new IllegalArgumentException("Couldn't obtain public key.");
}
encryptGen.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(publicKey));
encryptedOut = encryptGen.open(armoredOut, new byte[bufferSize]);
PGPCompressedDataGenerator compressGen = new PGPCompressedDataGenerator(PGPCompressedData.ZIP);
compressedOut = compressGen.open(encryptedOut);
PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator();
literalOut = literalGen.open(compressedOut, PGPLiteralDataGenerator.UTF8, "Response", new Date(), new byte[bufferSize]);
}
catch(PGPException e){
LOGGER.error(ExceptionUtils.getStackTrace(e));
}
catch(IOException e){
LOGGER.error(ExceptionUtils.getStackTrace(e));
}
return literalOut;
}
The returned OutputStream does not flush when I explicitly call flush(). Only when the close() method is called on each of the compressedOut, encryptedOut, and armoredOut OutputStreams are they actually flushed.
I've tried to modify the Bouncy Castle source code, but everything I do leads to some sort of malformed or corrupted PGP message that cannot be decrypted. I've also tried to modify the buffer size to make it smaller, larger, and the exact size of a single request, but this didn't work.
Does anyone have any suggestions on how to manually flush an encrypted OutputStream with Bouncy Castle?
回答1:
I had the same problem with BC. Look into the ArmoredOutputStream
class. Flush is empty and close doesn't call it's underlying outputstreams close. That means if you're working with ArmoredOutputStream
or ArmoredInputStream
you have to close ArmoredOutputStream
itself AND the underlying Outputstream
. The same for flush!
来源:https://stackoverflow.com/questions/28705211/flush-pgp-encrypted-bouncy-castle-outputstream-in-java