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.
The code for the same is:
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;
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(); }
/*
* 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') > 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");
}
}
}
The java terminal command is : C:\Users\anirudgu\eclipse-workspace\Decryptfile\bin>java PBEFileProcessor1 -d C:\Users\anirudgu\eclipse-workspace\Decryptfile\bin\PTO_data_26_06_2019_16_04.csv Passphase
But the error I am receiving is
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)
But I am able to encrypt this file with the same code. The jar file that are used are available here