Search code examples
javaencryptionbouncycastlepgp

JAVA :- PGP Decrypting using BouncyCastle those encrypted by GPG4win Kleopatra


i am using GPG4Win for encrypt the file and then BouncyCastle for decrypt file but code is not working

suppose i use BouncyCastle code for encrypt file and then use BouncyCastle decryption code its able to decrypt file and GPG4win also able to decrypt the file. all code in java

suppose file is encrypted by BouncyCastle its decrypt by GPG4win and BouncyCastle

org.bouncycastle.openpgp.PGPException: Exception starting decryption
at org.bouncycastle.openpgp.PGPPublicKeyEncryptedData.getDataStream(Unknown Source)
at org.bouncycastle.openpgp.PGPPublicKeyEncryptedData.getDataStream(Unknown Source)
at org.bouncycastle.openpgp.PGPPublicKeyEncryptedData.getDataStream(Unknown Source)
at com.pgp.util.KeyBasedFileProcessorUtil.decryptFile(KeyBasedFileProcessorUtil.java:183)
at com.pgp.encrypt.PGPDecryption.main(PGPDecryption.java:49)
Caused by: java.security.InvalidKeyException: Illegal key size
at javax.crypto.Cipher.a(DashoA13*..)
at javax.crypto.Cipher.init(DashoA13*..)
at javax.crypto.Cipher.init(DashoA13*..)
... 5 more
org.bouncycastle.openpgp.PGPException: Exception starting decryption
java.security.InvalidKeyException: Illegal key size
at javax.crypto.Cipher.a(DashoA13*..)
at javax.crypto.Cipher.init(DashoA13*..)
at javax.crypto.Cipher.init(DashoA13*..)
at org.bouncycastle.openpgp.PGPPublicKeyEncryptedData.getDataStream(Unknown Source)
at org.bouncycastle.openpgp.PGPPublicKeyEncryptedData.getDataStream(Unknown Source)
at org.bouncycastle.openpgp.PGPPublicKeyEncryptedData.getDataStream(Unknown Source)
at   com.pgp.util.KeyBasedFileProcessorUtil.decryptFile(KeyBasedFileProcessorUtil.java:183)
at com.pgp.encrypt.PGPDecryption.main(PGPDecryption.java:49)

my code is

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.PGPObjectFactory;
import org.bouncycastle.openpgp.PGPOnePassSignatureList;
import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
import org.bouncycastle.openpgp.PGPUtil;

import java.io.ByteArrayOutputStream;
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 java.io.*;
/**
* A simple utility class that encrypts/decrypts public key based
* encryption files.
* <p>
* To encrypt a file: KeyBasedFileProcessor -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: KeyBasedFileProcessor -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: 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 KeyBasedFileProcessorUtil
{
/**
 * A simple routine that opens a key ring file and loads the first available key suitable for
 * encryption.
 * 
 * @param in
 * @return
 * @throws IOException
 * @throws PGPException
 */
public static PGPPublicKey readPublicKey(
    InputStream    in)
    throws IOException, PGPException
{
    in = PGPUtil.getDecoderStream(in);

    PGPPublicKeyRingCollection        pgpPub = new PGPPublicKeyRingCollection(in);

    //
    // 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.
    //

    //
    // iterate through the key rings.
    //
    Iterator rIt = pgpPub.getKeyRings();

    while (rIt.hasNext())
    {
        PGPPublicKeyRing    kRing = (PGPPublicKeyRing)rIt.next();    
        Iterator                        kIt = kRing.getPublicKeys();

        while (kIt.hasNext())
        {
            PGPPublicKey    k = (PGPPublicKey)kIt.next();

            if (k.isEncryptionKey())
            {
                return k;
            }
        }
    }

    throw new IllegalArgumentException("Can't find encryption key in key ring.");
}

/**
 * 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
 * @throws PGPException
 * @throws NoSuchProviderException
 */
public 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(pass, "BC");
}

/**
 * decrypt the passed in message stream
 */
public static void decryptFile(
    InputStream in,
    InputStream keyIn,
    char[]      passwd,
    String      defaultFileName)
    throws Exception
{
    System.out.println("File Decrypting");
    System.out.println("File absulatePath :-");
    in = PGPUtil.getDecoderStream(in);

    try
    {
        PGPObjectFactory pgpF = new PGPObjectFactory(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
        //
        System.out.println("find the secret key");
        Iterator                    it = enc.getEncryptedDataObjects();
        PGPPrivateKey               sKey = null;
        PGPPublicKeyEncryptedData   pbe = null;
        PGPSecretKeyRingCollection  pgpSec = new PGPSecretKeyRingCollection(
            PGPUtil.getDecoderStream(keyIn));

        while (sKey == null && it.hasNext())
        {
            pbe = (PGPPublicKeyEncryptedData)it.next();
            sKey = findSecretKey(pgpSec, pbe.getKeyID(), passwd);

        }

        if (sKey == null)
        {
        System.out.println("--------------------");
        System.out.println("secret key for message not found.");
            throw new IllegalArgumentException("secret key for message not found.");
        }
        System.out.println("secret key for message found.");
        InputStream         clear = pbe.getDataStream(sKey, "BC");

        PGPObjectFactory    plainFact = new PGPObjectFactory(clear);

        Object              message = plainFact.nextObject();

        if (message instanceof PGPCompressedData)
        {
            PGPCompressedData   cData = (PGPCompressedData)message;
            PGPObjectFactory    pgpFact = new PGPObjectFactory(cData.getDataStream());

            message = pgpFact.nextObject();
        }

        if (message instanceof PGPLiteralData)
        {
            PGPLiteralData      ld = (PGPLiteralData)message;
            String              outFileName = ld.getFileName();
            if (ld.getFileName().length() == 0)
            {
                outFileName = defaultFileName;
            }


            InputStream    unc = ld.getInputStream();
            int    ch;

            while ((ch = unc.read()) >= 0)
            {
                fOut.write(ch);
            }
        }
        else if (message instanceof PGPOnePassSignatureList)
        {
            System.out.println("encrypted message contains a signed message - not literal data.");
            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)
    {
        e.printStackTrace();
        System.err.println(e);
        if (e.getUnderlyingException() != null)
        {
            e.getUnderlyingException().printStackTrace();
        }
    }
}

/*
    private static void decryptFile(
    InputStream in,
    InputStream keyIn,
    char[]      passwd)
    throws Exception
{    
    in = PGPUtil.getDecoderStream(in);

    try
    {
        PGPObjectFactory        pgpF = new PGPObjectFactory(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;

        while (sKey == null && it.hasNext())
        {
            pbe = (PGPPublicKeyEncryptedData)it.next();

            sKey = findSecretKey(keyIn, pbe.getKeyID(), passwd);
        }

        if (sKey == null)
        {
            throw new IllegalArgumentException("secret key for message not found.");
        }

        InputStream         clear = pbe.getDataStream(sKey, "BC");

        PGPObjectFactory    plainFact = new PGPObjectFactory(clear);

        PGPCompressedData   cData = (PGPCompressedData)plainFact.nextObject();

        InputStream         compressedStream = new BufferedInputStream(cData.getDataStream());
        PGPObjectFactory    pgpFact = new PGPObjectFactory(compressedStream);

        Object              message = pgpFact.nextObject();

        if (message instanceof PGPLiteralData)
        {
            PGPLiteralData       ld = (PGPLiteralData)message;

            FileOutputStream     fOut = new FileOutputStream(ld.getFileName());
            BufferedOutputStream bOut = new BufferedOutputStream(fOut);

            InputStream    unc = ld.getInputStream();
            int    ch;

            while ((ch = unc.read()) >= 0)
            {
                bOut.write(ch);
            }

            bOut.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();
        }
    }
}

*/

public static void encryptFile(
    OutputStream    out,
    String          fileName,
    PGPPublicKey    encKey,
    boolean         armor,
    boolean         withIntegrityCheck)
    throws IOException, NoSuchProviderException
{    
    if (armor)
    {
        out = new ArmoredOutputStream(out);
    }

    try
    {
        ByteArrayOutputStream       bOut = new ByteArrayOutputStream();
    PGPCompressedDataGenerator  comData = new PGPCompressedDataGenerator(1);
    PGPUtil.writeFileToLiteralData(comData.open(bOut), PGPLiteralData.BINARY, new File(fileName));

        comData.close();

        PGPEncryptedDataGenerator   cPk = new PGPEncryptedDataGenerator(PGPEncryptedData.CAST5, withIntegrityCheck, new SecureRandom(), "BC");

        cPk.addMethod(encKey);

        byte[]                bytes = bOut.toByteArray();

        OutputStream    cOut = cPk.open(out, bytes.length);

        cOut.write(bytes);

        cOut.close();

        out.close();
    }
    catch (PGPException e)
    {
        System.err.println(e);
        if (e.getUnderlyingException() != null)
        {
            e.getUnderlyingException().printStackTrace();
        }
    }
}    


public static void encryptFile1(
        OutputStream    out,
        String          fileName,
        PGPPrivateKey    encKey,
        boolean         armor,
        boolean         withIntegrityCheck)
        throws IOException, NoSuchProviderException
    {    
        if (armor)
        {
            out = new ArmoredOutputStream(out);
        }

        try
        {
            ByteArrayOutputStream       bOut = new ByteArrayOutputStream();
            PGPCompressedDataGenerator  comData = new PGPCompressedDataGenerator(1);
            PGPUtil.writeFileToLiteralData(comData.open(bOut), PGPLiteralData.BINARY, new File(fileName));

            comData.close();

            PGPEncryptedDataGenerator   cPk = new PGPEncryptedDataGenerator(PGPEncryptedData.CAST5, withIntegrityCheck, new SecureRandom(), "BC");

            cPk.addMethod((PGPPublicKey) encKey.getKey());


            byte[]                bytes = bOut.toByteArray();

            OutputStream    cOut = cPk.open(out, bytes.length);

            cOut.write(bytes);

            cOut.close();

            out.close();
        }
        catch (PGPException e)
        {
            System.err.println(e);
            if (e.getUnderlyingException() != null)
            {
                e.getUnderlyingException().printStackTrace();
            }
        }
    }     
  }

Decryption classs

public class PGPDecryption {

/**
 * 
 * @param args
 */
public static void main(String[] args) {
    // TODO Auto-generated method stub


    Properties prop=new Properties();
    try {
        prop.load(new FileInputStream("config.prop"));
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    FileInputStream keyOut=null;
    FileOutputStream out =null;
    Security.addProvider(new BouncyCastleProvider());
    try {
        System.out.println(prop.getProperty(Constant.PRIVATE_KEY));
        keyOut = new FileInputStream(prop.getProperty(Constant.PRIVATE_KEY));
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    try {
        KeyBasedFileProcessorUtil.decryptFile(new  FileInputStream(prop.getProperty(Constant.ENCRYPT_FILE_PATH)), keyOut, prop.getProperty(Constant.PRIVATE_FILE_PASS).toCharArray(), prop.getProperty(Constant.DECRYPT_FILE_OUTPUT_PATH)); 
        System.out.println("Decrypted File created with name of "+prop.getProperty(Constant.DECRYPT_FILE_OUTPUT_PATH));
    } catch (NoSuchProviderException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


    }

 }

Encryption class

public class PGPEncryption {

public static void main(String[] args) {
    // TODO Auto-generated method stub
    Properties prop=new Properties();
    try {
        File f=new File("config.prop");
        System.out.println(f.getAbsolutePath());
        prop.load(new FileInputStream(f));
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    FileInputStream keyIn=null;
    FileOutputStream out =null;
    Security.addProvider(new BouncyCastleProvider());
    try {
        System.out.println(prop.getProperty(Constant.PUBLIC_KEY));
        keyIn = new FileInputStream(prop.getProperty(Constant.PUBLIC_KEY));
        System.out.println("Encrypt File Path :-"+prop.getProperty(Constant.ENCRYPT_FILE_PATH));
        out= new FileOutputStream(new File(prop.getProperty(Constant.ENCRYPT_FILE_PATH)));
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    boolean armor = false;
    boolean integrityCheck = false;
    PGPPublicKey pubKey = null;
    try {
        System.out.println("Reading public key.........");
        pubKey = KeyBasedFileProcessorUtil.readPublicKey(keyIn);
        System.out.println("Public Key found...........");
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (PGPException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    try {
        System.out.println("File Encrypting............");
        KeyBasedFileProcessorUtil.encryptFile(out, prop.getProperty(Constant.SOURCE_FILE_PATH), pubKey, armor, integrityCheck);
        System.out.println("Encrypted File created with name of "+prop.getProperty(Constant.ENCRYPT_FILE_PATH));
    } catch (NoSuchProviderException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}

please help me i want to decrypt the file those encrypted by GPG4win


Solution

  • To solve this problem now, i am using Cryptix OpenPGP. its working properly without any error or exception.

    link to download Cryptix lib

    http://www.cryptix.org/

    in that download two project library Cryptix OpenPGP Cryptix JCE