JAVA: - PGP使用由GPG4win Kleopatra加密的BouncyCastle解密

时间:2014-09-13 11:26:20

标签: java encryption bouncycastle pgp

我正在使用GPG4Win加密文件,然后使用BouncyCastle进行解密文件,但代码无法正常工作

假设我使用BouncyCastle代码加密文件,然后使用BouncyCastle解密代码,它能够解密文件,GPG4win也能够解密文件。 java中的所有代码

假设文件由BouncyCastle加密,由GPG4win和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)

我的代码是

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

解密课

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


    }

 }

加密类

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

}

请帮助我,我想解密那些由GPG4win加密的文件

1 个答案:

答案 0 :(得分:0)

现在要解决这个问题,我使用的是Cryptix OpenPGP。 它的工作正常,没有任何错误或例外。

链接下载Cryptix lib

http://www.cryptix.org/

在那个下载两个项目库中 Cryptix OpenPGP Cryptix JCE