Last active
May 10, 2017 23:35
-
-
Save magJ/5021db9551737960bf85d216ec9f414c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-----BEGIN PGP PUBLIC KEY BLOCK----- | |
Version: GnuPG v2.0.22 (GNU/Linux) | |
base64 encoded key data here | |
-----END PGP PUBLIC KEY BLOCK----- |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Gist written in response to: http://stackoverflow.com/questions/43783943/what-algorithm-to-use-when-creating-an-encrypting-log4j-appender