Below is simple code almost entirely extracted from this project that just encrypts a file with a PGP public key.
package com.nestorurquiza.utils;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Date;
import java.util.Iterator;
import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPCompressedData;
import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
import org.bouncycastle.openpgp.PGPEncryptedData;
import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
import org.bouncycastle.openpgp.PGPLiteralData;
import org.bouncycastle.openpgp.PGPLiteralDataGenerator;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
import org.bouncycastle.openpgp.PGPUtil;
/**
*
* Code in part extracted from http://sourceforge.net/projects/ppgp/
* A nice GUI to generate your own keys, encrypt and sign documents using PGP
*
* @author nestor
*
*/
public class PgpUtils {
private final static int BUFFER_SIZE = 1 << 16;
private static PGPPublicKey readPublicKeyFromCollection2(InputStream in) throws Exception {
in = PGPUtil.getDecoderStream(in);
PGPPublicKeyRing pkRing = null;
PGPPublicKeyRingCollection pkCol = new PGPPublicKeyRingCollection(in);
Iterator it = pkCol.getKeyRings();
while (it.hasNext()) {
pkRing = (PGPPublicKeyRing) it.next();
Iterator pkIt = pkRing.getPublicKeys();
while (pkIt.hasNext()) {
PGPPublicKey key = (PGPPublicKey) pkIt.next();
if (key.isEncryptionKey())
return key;
}
}
return null;
}
/**
* Encrypts a file using a public key
*
* @param decryptedFilePath
* @param encryptedFilePath
* @param encKeyPath
* @param armor
* @param withIntegrityCheck
* @throws Exception
*/
public static void encryptFile(String decryptedFilePath,
String encryptedFilePath,
String encKeyPath,
boolean armor,
boolean withIntegrityCheck)
throws Exception{
OutputStream out = new FileOutputStream(encryptedFilePath);
FileInputStream pubKey = new FileInputStream(encKeyPath);
PGPPublicKey encKey = readPublicKeyFromCollection2(pubKey);
Security.addProvider(new BouncyCastleProvider());
if (armor)
out = new ArmoredOutputStream(out);
// Init encrypted data generator
PGPEncryptedDataGenerator encryptedDataGenerator =
new PGPEncryptedDataGenerator(PGPEncryptedData.CAST5, withIntegrityCheck, new SecureRandom(),"BC");
encryptedDataGenerator.addMethod(encKey);
OutputStream encryptedOut = encryptedDataGenerator.open(out, new byte[BUFFER_SIZE]);
// Init compression
PGPCompressedDataGenerator compressedDataGenerator = new PGPCompressedDataGenerator(PGPCompressedData.ZIP);
OutputStream compressedOut = compressedDataGenerator.open(encryptedOut);
PGPLiteralDataGenerator literalDataGenerator = new PGPLiteralDataGenerator();
OutputStream literalOut = literalDataGenerator.open(compressedOut, PGPLiteralData.BINARY, decryptedFilePath, new Date(), new byte[BUFFER_SIZE]);
FileInputStream inputFileStream = new FileInputStream(decryptedFilePath);
byte[] buf = new byte[BUFFER_SIZE];
int len;
while((len = inputFileStream.read(buf))>0){
literalOut.write(buf,0,len);
}
literalOut.close();
literalDataGenerator.close();
compressedOut.close();
compressedDataGenerator.close();
encryptedOut.close();
encryptedDataGenerator.close();
inputFileStream.close();
out.close();
}
}
The Unit test showing how to use it:
package com.nestorurquiza.utils;
import java.io.IOException;
import org.junit.Test;
import org.xml.sax.SAXException;
public class PgpUtilsTest {
@Ignore
@Test
public void encryptTest() throws IOException, Exception, SAXException {
String publicKeyFilePath = "/Users/nestor/Downloads/somePublicKey.pgp";
String decryptedFilePath = "/Users/nestor/Downloads/someFile.csv";
String encryptedFilePath = "/Users/nestor/Downloads/someFile.csv.enc";
PgpUtils.encryptFile(decryptedFilePath, encryptedFilePath, publicKeyFilePath, false, true);
}
}