title: Using PBEFileProcessor to decrypt file provided by bouncycastle
body: <p>I am facing some issue in decrypting a pgp encrypted file. I have the pass phase and the file with me. Now to decrypt it I need to use a class PBEFileProcessor (best guess) provided by bouncycastle in their jar. I have included the jar in my eclipse project and have made a new class which calls this class to decrypt the file. But i am having hard time debugging it.</p>
  
  <p>The code for the same is: </p>
  
  <pre><code>import java.io.BufferedInputStream;import java.io.BufferedOutputStream;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 org.bouncycastle.bcpg.ArmoredOutputStream;import org.bouncycastle.bcpg.CompressionAlgorithmTags;import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;import org.bouncycastle.jce.provider.BouncyCastleProvider;import org.bouncycastle.openpgp.PGPCompressedData;import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;import org.bouncycastle.openpgp.PGPEncryptedDataList;import org.bouncycastle.openpgp.PGPException;import org.bouncycastle.openpgp.PGPLiteralData;import org.bouncycastle.openpgp.PGPPBEEncryptedData;import org.bouncycastle.openpgp.PGPUtil;import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory;import rg.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;import org.bouncycastle.openpgp.operator.jcajce.JcePBEDataDecryptorFactoryBuilder;import org.bouncycastle.openpgp.operator.jcajce.JcePBEKeyEncryptionMethodGenerator;import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;import org.bouncycastle.util.io.Streams; 
  </code></pre>
  
  <p>public class PBEFileProcessor1 {
      private static void decryptFile(String inputFileName, char[] passPhrase)
          throws IOException, NoSuchProviderException, PGPException
      {
          InputStream in = new BufferedInputStream(new FileInputStream(inputFileName));
          decryptFile(in, passPhrase);
          in.close();
      }</p>
  
  <pre><code>/*
   * decrypt the passed in message stream
   */
  private static void decryptFile(
      InputStream    in,
      char[]         passPhrase)
      throws IOException, NoSuchProviderException, PGPException
  {
      in = PGPUtil.getDecoderStream(in);
  
      JcaPGPObjectFactory        pgpF = new JcaPGPObjectFactory(in);
      PGPEncryptedDataList    enc;
      Object                  o = pgpF.nextObject();
  
      if (o instanceof PGPEncryptedDataList)
      {
          enc = (PGPEncryptedDataList)o;
      }
      else
      {
          enc = (PGPEncryptedDataList)pgpF.nextObject();
      }
  
      PGPPBEEncryptedData pbe = (PGPPBEEncryptedData)enc.get(0);
  
      InputStream clear = pbe.getDataStream(new JcePBEDataDecryptorFactoryBuilder(new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build()).setProvider("BC").build(passPhrase));
  
      JcaPGPObjectFactory        pgpFact = new JcaPGPObjectFactory(clear);
  
      //
      // if we're trying to read a file generated by someone other than us
      // the data might not be compressed, so we check the return type from
      // the factory and behave accordingly.
      //
      o = pgpFact.nextObject();
      if (o instanceof PGPCompressedData)
      {
          PGPCompressedData   cData = (PGPCompressedData)o;
  
          pgpFact = new JcaPGPObjectFactory(cData.getDataStream());
  
          o = pgpFact.nextObject();
      }
  
      PGPLiteralData ld = (PGPLiteralData)o;
      InputStream unc = ld.getInputStream();
  
      OutputStream fOut = new BufferedOutputStream(new FileOutputStream(ld.getFileName()));
  
      Streams.pipeAll(unc, fOut);
  
      fOut.close();
  
      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");
      }
  }
  
  private static void encryptFile(
      String          outputFileName,
      String          inputFileName,
      char[]          passPhrase,
      boolean         armor,
      boolean         withIntegrityCheck)
      throws IOException, NoSuchProviderException
  {
      OutputStream out = new BufferedOutputStream(new FileOutputStream(outputFileName));
      encryptFile(out, inputFileName, passPhrase, armor, withIntegrityCheck);
      out.close();
  }
  
  private static void encryptFile(
      OutputStream    out,
      String          fileName,
      char[]          passPhrase,
      boolean         armor,
      boolean         withIntegrityCheck)
      throws IOException, NoSuchProviderException
  {
      if (armor)
      {
          out = new ArmoredOutputStream(out);
      }
  
      try
      {
          byte[] compressedData = BouncyCastlePGPExampleUtil.compressFile(fileName, CompressionAlgorithmTags.ZIP);
  
          PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5)
              .setWithIntegrityPacket(withIntegrityCheck).setSecureRandom(new SecureRandom()).setProvider("BC"));
  
          encGen.addMethod(new JcePBEKeyEncryptionMethodGenerator(passPhrase).setProvider("BC"));
  
          OutputStream encOut = encGen.open(out, compressedData.length);
  
          encOut.write(compressedData);
          encOut.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[0].equals("-e"))
      {
          if (args[1].equals("-a") || args[1].equals("-ai") || args[1].equals("-ia"))
          {
              encryptFile(args[2] + ".asc", args[2], args[3].toCharArray(), true, (args[1].indexOf('i') &gt; 0));
          }
          else if (args[1].equals("-i"))
          {
              encryptFile(args[2] + ".bpg", args[2], args[3].toCharArray(), false, true);
          }
          else
          {
              encryptFile(args[1] + ".bpg", args[1], args[2].toCharArray(), false, false);
          }
      }
      else if (args[0].equals("-d"))
      {
          decryptFile(args[1], args[2].toCharArray());
      }
      else
      {
          System.err.println("usage: PBEFileProcessor -e [-ai]|-d file passPhrase");
      }
  }
  </code></pre>
  
  <p>}</p>
  
  <p>The java terminal command is : <code>C:\Users\anirudgu\eclipse-workspace\Decryptfile\bin&gt;java PBEFileProcessor1 -d C:\Users\anirudgu\eclipse-workspace\Decryptfile\bin\PTO_data_26_06_2019_16_04.csv Passphase</code></p>
  
  <p>But the error I am receiving is </p>
  
  <p><strong>Exception in thread "main" java.lang.ClassCastException: org.bouncycastle.openpgp.PGPPublicKeyEncryptedData cannot be cast to org.bouncycastle.openpgp.PGPPB
  EEncryptedData
          at PBEFileProcessor1.decryptFile(PBEFileProcessor1.java:90)
          at PBEFileProcessor1.decryptFile(PBEFileProcessor1.java:60)
          at PBEFileProcessor1.main(PBEFileProcessor1.java:215)</strong></p>
  
  <p>But I am able to encrypt this file with the same code.
  The jar file that are used are available <a href="https://www.bouncycastle.org/latest_releases.html" rel="nofollow noreferrer">here</a></p>