Skip to content

Instantly share code, notes, and snippets.

@magJ
Last active May 10, 2017 23:35
Show Gist options
  • Save magJ/5021db9551737960bf85d216ec9f414c to your computer and use it in GitHub Desktop.
Save magJ/5021db9551737960bf85d216ec9f414c to your computer and use it in GitHub Desktop.
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.SimpleLayout;
import org.bouncycastle.openpgp.PGPException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
public class Main {
private final static Logger LOG = Logger.getLogger(Main.class);
public static void main(String... args) throws IOException, PGPException {
PGPRollingFileAppender blah = new PGPRollingFileAppender("example.log", Files.readAllBytes(Paths.get("public_key.asc")));
blah.setLayout(new SimpleLayout());
BasicConfigurator.configure(blah);
LOG.info("This is a test");
LOG.error("This is some error.");
//Ensure log4j shuts down and flushes log file gracefully
LogManager.shutdown();
}
}
import org.apache.log4j.RollingFileAppender;
import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.*;
import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;
import java.io.*;
import java.util.Date;
public class PGPRollingFileAppender extends RollingFileAppender {
private static final BouncyCastleProvider BOUNCY_CASTLE_PROVIDER = new BouncyCastleProvider();
private static final int BUFFER_SIZE = 65536;
private final PGPPublicKey pgpPublicKey;
private final int encryptionAlgorithm;
public PGPRollingFileAppender(String fileName, byte[] publicKey) throws IOException, PGPException {
this.fileName = fileName;
this.pgpPublicKey = readPublicKey(new ByteArrayInputStream(publicKey));
this.encryptionAlgorithm = PGPEncryptedData.AES_128;//PGPEncryptedData.AES_256 requires enabling jre unlimited strength crypto
rollOver();//Immediate rollover so we only have one PGP message per file
}
private static PGPPublicKey readPublicKey(InputStream input) throws IOException, PGPException {
PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(
org.bouncycastle.openpgp.PGPUtil.getDecoderStream(input), new JcaKeyFingerprintCalculator());
// we just loop through the collection till we find a key suitable for encryption, in the real
// world you would probably want to be a bit smarter about this.
for(PGPPublicKeyRing keyRing : pgpPub) {
for(PGPPublicKey key : keyRing) {
if(key.isEncryptionKey()) {
return key;
}
}
}
throw new IllegalArgumentException("Can't find encryption key in key ring.");
}
@Override
protected OutputStreamWriter createWriter(OutputStream os) {
final PGPEncryptedDataGenerator pgpEncryptedDataGenerator =
new PGPEncryptedDataGenerator(
new JcePGPDataEncryptorBuilder(encryptionAlgorithm)
.setProvider(BOUNCY_CASTLE_PROVIDER));
pgpEncryptedDataGenerator.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(pgpPublicKey).setProvider(BOUNCY_CASTLE_PROVIDER));
//You can remove the ArmoredOutputStream in favour of binary output which will take up less space, but armour makes it easier to debug how this works
final ArmoredOutputStream armoredOutputStream = new ArmoredOutputStream(os);
try {
final OutputStream encryptedOutPutStream = pgpEncryptedDataGenerator.open(armoredOutputStream, new byte[BUFFER_SIZE]);
final PGPLiteralDataGenerator pgpLiteralDataGenerator = new PGPLiteralDataGenerator();
final OutputStream dataOutputStream = pgpLiteralDataGenerator.open(encryptedOutPutStream, PGPLiteralData.BINARY, "", new Date(), new byte[BUFFER_SIZE]);
return super.createWriter(new ClosingOutputStream(dataOutputStream, encryptedOutPutStream, armoredOutputStream, os));
} catch (IOException | PGPException e) {
throw new RuntimeException(e);
}
}
/**
* Helper class to make sure all streams are closed properly
*/
private class ClosingOutputStream extends FilterOutputStream {
Closeable[] otherStuffToClose;
public ClosingOutputStream(OutputStream out, Closeable... otherStuffToClose) {
super(out);
this.otherStuffToClose = otherStuffToClose;
}
@Override
public void close() throws IOException {
super.close();
for(Closeable outputStream : otherStuffToClose){
outputStream.close();
}
}
}
}
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2.0.22 (GNU/Linux)
base64 encoded key data here
-----END PGP PUBLIC KEY BLOCK-----
@magJ
Copy link
Author

magJ commented May 10, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment