Pgp File Encryption in Java Example

You can use the crypto library 'Bouncy Castle' to encrypt a file using a PGP Public key in Ascii-format. The following code is taken from the examples section of Bouncy Castle that is located here: https://github.com/bcgit/bc-java/tree/master/pg/src/main/java/org/bouncycastle/openpgp/examples.

You do need the two files KeyBasedLargeFileProcessor.java and PGPExampleUtil.java plus the libraries itself; get the latest versions here: https://www.bouncycastle.org/latest_releases.html (you need the bcprov-xxx.jar and bcpg-xxx.jar to run the example).

As the example is a command line application you need to pass the information like

          -e -a plaintext.txt java_pgp_encrypt_publickey.asc                  

where -e = encryption, -a = ascii output, plaintext.txt is your file to get encrypted and java_pgp_encrypt_publickey.asc = the public key.

There are some other options but they depend on the third party requests.

Please take care about the notes in KeyBasedLargeFileProcessor.java - this is just a working example.

Usually there is not extra output but a new file in the current directory with the filename plaintext.txt.asc that looks like

          -----BEGIN PGP MESSAGE----- Version: BCPG v1.66  hQEMAyr8BYmnLERrAQf/SaG7yIORewag0fziemyEmWq+sGJT3TiLIoVCEo+PjDfY XyuXybIr/q5Q7tE3WcubkXzVIuShB2x2r8zaHP3rhtzDfuRS13S5QBM1LZ9KIcvg +//OoeS1kfKfJnYfAQR1VCKWBkOQtSCIyMWGmqkrV2xEC8xzAo2cwXCBS2F7LYRE vnmJGnr4ANFdbSlzRffBPJCcggk9RqDXXJjU31gCqFT+lpgc48Hf6OfRff7x5I2b 5++PH1UPKFIZhalnFE2UQ9DVbzJd2FaciUKhcM9nQSGKoNKy3o1wevrtive8VIuM JjgV0ql+3MGCVVYL0tBnDdjdbmHV5pcZX9aI147esclPItwZQHTHTtaxTUKTJZeQ 4YgMas+o0faWLUilaeNvNa8PqxLy9gPGzMxUj2/P1narGs4bbivUooLJO73NKV4B u3on8l/Es4vVLNoZpJv0kw== =IZ8I -----END PGP MESSAGE-----                  

Edit Aug. 12th 2020: I made a fresh download of PGP Desktop x64 version 10.1.1, generated a sample keypair and exported the public key ("-----BEGIN PGP PUBLIC KEY BLOCK-----..."). I used this key with the mentioned options and created a encrypted file ("-----BEGIN PGP MESSAGE-----..."). This file was used as input for the PGP Viewer and it was decrypted like expected, so something in your environment seems not to work as expected (or the wrong public key was in use or or or):

enter image description here

As links may go away here are the source codes as well.

class KeyBasedLargeFileProcessor.java

          import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.NoSuchProviderException; import java.security.SecureRandom; import java.security.Security; 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.PGPEncryptedDataList; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPOnePassSignatureList; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData; import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory; import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator; import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator; import org.bouncycastle.util.io.Streams;  /**  * A simple utility class that encrypts/decrypts public key based  * encryption large files.  * <p>  * To encrypt a file: KeyBasedLargeFileProcessor -e [-a|-ai] fileName publicKeyFile.<br>  * If -a is specified the output file will be "ascii-armored".  * If -i is specified the output file will be have integrity checking added.  * <p>  * To decrypt: KeyBasedLargeFileProcessor -d fileName secretKeyFile passPhrase.  * <p>  * Note 1: this example will silently overwrite files, nor does it pay any attention to  * the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase  * will have been used.  * <p>  * Note 2: this example generates partial packets to encode the file, the output it generates  * will not be readable by older PGP products or products that don't support partial packet  * encoding.  * <p>  * Note 3: if an empty file name has been specified in the literal data object contained in the  * encrypted packet a file with the name filename.out will be generated in the current working directory.  */ public class KeyBasedLargeFileProcessor /*    file taken from https://github.com/bcgit/bc-java/tree/master/pg/src/main/java/org/bouncycastle/openpgp/examples    get bouncy castle here: https://www.bouncycastle.org/latest_releases.html    i used the bcprov-jdk15on-166.jar and bcpg-jdk15on-166.jar at the time of writing */ {     private static void decryptFile(             String inputFileName,             String keyFileName,             char[] passwd,             String defaultFileName)             throws IOException, NoSuchProviderException     {         InputStream in = new BufferedInputStream(new FileInputStream(inputFileName));         InputStream keyIn = new BufferedInputStream(new FileInputStream(keyFileName));         decryptFile(in, keyIn, passwd, defaultFileName);         keyIn.close();         in.close();     }      /**      * decrypt the passed in message stream      */     private static void decryptFile(             InputStream in,             InputStream keyIn,             char[]      passwd,             String      defaultFileName)             throws IOException, NoSuchProviderException     {         in = PGPUtil.getDecoderStream(in);          try         {             JcaPGPObjectFactory        pgpF = new JcaPGPObjectFactory(in);             PGPEncryptedDataList    enc;              Object                  o = pgpF.nextObject();             //             // the first object might be a PGP marker packet.             //             if (o instanceof PGPEncryptedDataList)             {                 enc = (PGPEncryptedDataList)o;             }             else             {                 enc = (PGPEncryptedDataList)pgpF.nextObject();             }              //             // find the secret key             //             Iterator                    it = enc.getEncryptedDataObjects();             PGPPrivateKey               sKey = null;             PGPPublicKeyEncryptedData   pbe = null;             PGPSecretKeyRingCollection  pgpSec = new PGPSecretKeyRingCollection(                     PGPUtil.getDecoderStream(keyIn), new JcaKeyFingerprintCalculator());              while (sKey == null && it.hasNext())             {                 pbe = (PGPPublicKeyEncryptedData)it.next();                  sKey = PGPExampleUtil.findSecretKey(pgpSec, pbe.getKeyID(), passwd);             }              if (sKey == null)             {                 throw new IllegalArgumentException("secret key for message not found.");             }              InputStream         clear = pbe.getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider("BC").build(sKey));              JcaPGPObjectFactory    plainFact = new JcaPGPObjectFactory(clear);              PGPCompressedData   cData = (PGPCompressedData)plainFact.nextObject();              InputStream         compressedStream = new BufferedInputStream(cData.getDataStream());             JcaPGPObjectFactory    pgpFact = new JcaPGPObjectFactory(compressedStream);              Object              message = pgpFact.nextObject();              if (message instanceof PGPLiteralData)             {                 PGPLiteralData ld = (PGPLiteralData)message;                  String outFileName = ld.getFileName();                 if (outFileName.length() == 0)                 {                     outFileName = defaultFileName;                 }                  InputStream unc = ld.getInputStream();                 OutputStream fOut =  new BufferedOutputStream(new FileOutputStream(outFileName));                  Streams.pipeAll(unc, fOut);                  fOut.close();             }             else if (message instanceof PGPOnePassSignatureList)             {                 throw new PGPException("encrypted message contains a signed message - not literal data.");             }             else             {                 throw new PGPException("message is not a simple encrypted file - type unknown.");             }              if (pbe.isIntegrityProtected())             {                 if (!pbe.verify())                 {                     System.err.println("message failed integrity check");                 }                 else                 {                     System.err.println("message integrity check passed");                 }             }             else             {                 System.err.println("no message integrity check");             }         }         catch (PGPException e)         {             System.err.println(e);             if (e.getUnderlyingException() != null)             {                 e.getUnderlyingException().printStackTrace();             }         }     }      private static void encryptFile(             String          outputFileName,             String          inputFileName,             String          encKeyFileName,             boolean         armor,             boolean         withIntegrityCheck)             throws IOException, NoSuchProviderException, PGPException     {         OutputStream out = new BufferedOutputStream(new FileOutputStream(outputFileName));         PGPPublicKey encKey = PGPExampleUtil.readPublicKey(encKeyFileName);         encryptFile(out, inputFileName, encKey, armor, withIntegrityCheck);         out.close();     }      private static void encryptFile(             OutputStream    out,             String          fileName,             PGPPublicKey    encKey,             boolean         armor,             boolean         withIntegrityCheck)             throws IOException, NoSuchProviderException     {         if (armor)         {             out = new ArmoredOutputStream(out);         }          try         {             PGPEncryptedDataGenerator   cPk = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(withIntegrityCheck).setSecureRandom(new SecureRandom()).setProvider("BC"));              cPk.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(encKey).setProvider("BC"));              OutputStream                cOut = cPk.open(out, new byte[1 << 16]);              PGPCompressedDataGenerator  comData = new PGPCompressedDataGenerator(                     PGPCompressedData.ZIP);              PGPUtil.writeFileToLiteralData(comData.open(cOut), PGPLiteralData.BINARY, new File(fileName), new byte[1 << 16]);              comData.close();              cOut.close();              if (armor)             {                 out.close();             }         }         catch (PGPException e)         {             System.err.println(e);             if (e.getUnderlyingException() != null)             {                 e.getUnderlyingException().printStackTrace();             }         }     }      public static void main(             String[] args)             throws Exception     {         Security.addProvider(new BouncyCastleProvider());          if (args.length == 0)         {             System.err.println("usage: KeyBasedLargeFileProcessor -e|-d [-a|ai] file [secretKeyFile passPhrase|pubKeyFile]");             return;         }          if (args[0].equals("-e"))         {             if (args[1].equals("-a") || args[1].equals("-ai") || args[1].equals("-ia"))             {                 encryptFile(args[2] + ".asc", args[2], args[3], true, (args[1].indexOf('i') > 0));             }             else if (args[1].equals("-i"))             {                 encryptFile(args[2] + ".bpg", args[2], args[3], false, true);             }             else             {                 encryptFile(args[1] + ".bpg", args[1], args[2], false, false);             }         }         else if (args[0].equals("-d"))         {             decryptFile(args[1], args[2], args[3].toCharArray(), new File(args[1]).getName() + ".out");         }         else         {             System.err.println("usage: KeyBasedLargeFileProcessor -d|-e [-a|ai] file [secretKeyFile passPhrase|pubKeyFile]");         }     } }                  

class PGPExampleUtil.java

          import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.security.NoSuchProviderException; import java.util.Iterator;  import org.bouncycastle.openpgp.PGPCompressedDataGenerator; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator; import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;  class PGPExampleUtil {     static byte[] compressFile(String fileName, int algorithm) throws IOException     {         ByteArrayOutputStream bOut = new ByteArrayOutputStream();         PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(algorithm);         PGPUtil.writeFileToLiteralData(comData.open(bOut), PGPLiteralData.BINARY,                 new File(fileName));         comData.close();         return bOut.toByteArray();     }      /**      * Search a secret key ring collection for a secret key corresponding to keyID if it      * exists.      *      * @param pgpSec a secret key ring collection.      * @param keyID keyID we want.      * @param pass passphrase to decrypt secret key with.      * @return the private key.      * @throws PGPException      * @throws NoSuchProviderException      */     static PGPPrivateKey findSecretKey(PGPSecretKeyRingCollection pgpSec, long keyID, char[] pass)             throws PGPException, NoSuchProviderException     {         PGPSecretKey pgpSecKey = pgpSec.getSecretKey(keyID);          if (pgpSecKey == null)         {             return null;         }          return pgpSecKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(pass));     }      static PGPPublicKey readPublicKey(String fileName) throws IOException, PGPException     {         InputStream keyIn = new BufferedInputStream(new FileInputStream(fileName));         PGPPublicKey pubKey = readPublicKey(keyIn);         keyIn.close();         return pubKey;     }      /**      * A simple routine that opens a key ring file and loads the first available key      * suitable for encryption.      *      * @param input data stream containing the public key data      * @return the first public key found.      * @throws IOException      * @throws PGPException      */     static PGPPublicKey readPublicKey(InputStream input) throws IOException, PGPException     {         PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(                 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.         //          Iterator keyRingIter = pgpPub.getKeyRings();         while (keyRingIter.hasNext())         {             PGPPublicKeyRing keyRing = (PGPPublicKeyRing)keyRingIter.next();              Iterator keyIter = keyRing.getPublicKeys();             while (keyIter.hasNext())             {                 PGPPublicKey key = (PGPPublicKey)keyIter.next();                  if (key.isEncryptionKey())                 {                     return key;                 }             }         }          throw new IllegalArgumentException("Can't find encryption key in key ring.");     }      static PGPSecretKey readSecretKey(String fileName) throws IOException, PGPException     {         InputStream keyIn = new BufferedInputStream(new FileInputStream(fileName));         PGPSecretKey secKey = readSecretKey(keyIn);         keyIn.close();         return secKey;     }      /**      * A simple routine that opens a key ring file and loads the first available key      * suitable for signature generation.      *      * @param input stream to read the secret key ring collection from.      * @return a secret key.      * @throws IOException on a problem with using the input stream.      * @throws PGPException if there is an issue parsing the input stream.      */     static PGPSecretKey readSecretKey(InputStream input) throws IOException, PGPException     {         PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(                 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.         //          Iterator keyRingIter = pgpSec.getKeyRings();         while (keyRingIter.hasNext())         {             PGPSecretKeyRing keyRing = (PGPSecretKeyRing)keyRingIter.next();              Iterator keyIter = keyRing.getSecretKeys();             while (keyIter.hasNext())             {                 PGPSecretKey key = (PGPSecretKey)keyIter.next();                  if (key.isSigningKey())                 {                     return key;                 }             }         }          throw new IllegalArgumentException("Can't find signing key in key ring.");     } }                  

brownlitine.blogspot.com

Source: https://stackoverflow.com/questions/63351345/java-pgp-encrypt-file-with-public-key-in-asc-file

0 Response to "Pgp File Encryption in Java Example"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel