Pgp 签名+加密然后解密+验证

Pgp sign+encrypt then decrypt+verify

在进行符号加密然后解密和验证时,我在验证时不断在流中获取未知对象。消息完整性检查已通过,但是当我尝试在解密后的下一行中进行验证时,出现了上述错误。

    private static void encryptFile(
    String outFileName,
    OutputStream out,
    String fileName,
    PGPPublicKey encKey,
    String sKeyFileName,
    char[] passPhrase,
    boolean armor,
    boolean withIntegrityCheck)
    throws Exception
{
    if (armor)
    {
        out = new ArmoredOutputStream(out);
    }

    try
    {


        byte[] bytes = PGPKeyUtil.compressFile(fileName, CompressionAlgorithmTags.ZIP);


        PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(
            PGPEncryptedData.CAST5, withIntegrityCheck, new SecureRandom(), "BC");
        encGen.addMethod(encKey);

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

        cOut.write(bytes);
        cOut.close();
        out.close();

        cOut.close();


        if (armor)
        {
            out.close();
        }

        encGen.close();

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

public static void signFile(
    String          fileName,
    InputStream keyIn,
    OutputStream    out,
    char[]          pass,
    boolean         armor)
    throws IOException, NoSuchAlgorithmException, NoSuchProviderException, PGPException, SignatureException
{
    if (armor)
    {
        out = new ArmoredOutputStream(out);
    }

    PGPSecretKey pgpSec = readSecretKey(keyIn);
    PGPPrivateKey pgpPrivKey = pgpSec.extractPrivateKey(pass, "BC");
    PGPSignatureGenerator sGen = new PGPSignatureGenerator(pgpSec.getPublicKey().getAlgorithm(), PGPUtil.SHA1, "BC");

    sGen.initSign(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);

    Iterator it = pgpSec.getPublicKey().getUserIDs();
    if (it.hasNext())
    {
        PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();

        spGen.setSignerUserID(false, (String)it.next());
        sGen.setHashedSubpackets(spGen.generate());
    }

    PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator(
        PGPCompressedData.ZLIB);

    BCPGOutputStream bOut = new BCPGOutputStream(cGen.open(out));

    sGen.generateOnePassVersion(false).encode(bOut);

    File file = new File(fileName);
    PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator();
    OutputStream                lOut = lGen.open(bOut, PGPLiteralData.BINARY, file);
    FileInputStream fIn = new FileInputStream(file);
    int                         ch = 0;

    while ((ch = fIn.read()) >= 0)
    {
        lOut.write(ch);
        sGen.update((byte)ch);
    }

    lGen.close();


    sGen.generate().encode(bOut);

    cGen.close();
    bOut.close();
    fIn.close();
    lOut.close();

    if (armor)
    {
        out.close();
    }
    System.out.println("Successfully signed");
}

首先我使用 signFile 签名,然后我使用加密方法加密文件。

我测试了你的代码

加密并签署我的一些文本文件,然后再解密。

那我解密的时候也报错

消息是-

unknown object in stream: 56
java.io.IOException: unknown object in stream: 56
    at org.bouncycastle.openpgp.PGPObjectFactory.nextObject(Unknown Source)
    at FileEncryptTest._decrypt(FileEncryptTest.java:205)
    at FileEncryptTest.decryptFile(FileEncryptTest.java:170)
    at FileEncryptTest.main(FileEncryptTest.java:157)

我不确定与你的消息是否相同,但 signFile 方法必须如下所示,

private static void signFile(String fileName, InputStream keyIn, OutputStream out, char[] pass, boolean armor)
        throws GeneralSecurityException, IOException, PGPException {
    if (armor) {
        out = new ArmoredOutputStream(out);
    }

    PGPSecretKey pgpSec = readSecretKey(keyIn);
    PGPPrivateKey pgpPrivKey = pgpSec
            .extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(pass));
    PGPSignatureGenerator sGen = new PGPSignatureGenerator(
            new JcaPGPContentSignerBuilder(pgpSec.getPublicKey().getAlgorithm(), PGPUtil.SHA1).setProvider("BC"));

    sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);

    BCPGOutputStream bOut = new BCPGOutputStream(out);

    InputStream fIn = new BufferedInputStream(new FileInputStream(fileName));

    byte[] buf = new byte[1024];
    int len;
    while ((len = fIn.read(buf)) > 0) {
        sGen.update(buf, 0, len);
    }

    //int ch;
    //while ((ch = fIn.read()) >= 0) {
    //  sGen.update((byte) ch);
    //}

    fIn.close();

    sGen.generate().encode(bOut);

    if (armor) {
        out.close();
    }

    out.close();
    bOut.close();
}

我的 bouncycastle 库正是 bcpg-jdk15on-158.jar - 最新的。 因此,API 的某些部分代码可能有所不同。

我在我的主要方法中添加了它。

首先,我的私有&public密钥文件声明。

private static File publicKeyFile = new File("resource/PGP1D0.pkr");
private static File privateKeyFile = new File("resource/PGP1D0.skr");
private static String privateKeyPassword = "passphrase";
isEncrypt 为真时,

签名并加密文件,否则解密文件。 当 isEncrypt 标志为真时,原始文件在加密签名后为 tile_doc.in 和 tile_doc.signed.in,然后让标志为假和 运行。 在资源文件夹中可以看到tile_doc.out文件

private static final boolean isEncrypt = false;
public static void main(String[] args) {
    Security.addProvider(new BouncyCastleProvider());

    String outFileName = "resource/tile_doc.signed.in";
    String recoverFile = "resource/tile_doc.out";
    OutputStream out = null;
    InputStream keyIn = null;
    InputStream outFileIn = null;
    String fileName = "resource/tile_doc.in";

    PGPPublicKey encKey = null;

    char[] passPhrase = privateKeyPassword.toCharArray();
    boolean armor = false;
    boolean withIntegrityCheck = true;

    if (isEncrypt) {
        try {
            keyIn = new BufferedInputStream(new FileInputStream(privateKeyFile));
            out = new BufferedOutputStream(new FileOutputStream(outFileName));
            encKey = readPublicKeyFromCol(new FileInputStream(publicKeyFile));
            //
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


            try {
                signFile(fileName, keyIn, out, passPhrase, armor);

                out = new BufferedOutputStream(new FileOutputStream(outFileName));

            } catch (GeneralSecurityException | IOException | PGPException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        encryptFile(outFileName, out, fileName, encKey, passPhrase, armor, withIntegrityCheck);
    } else {


        try {
            keyIn = new BufferedInputStream(new FileInputStream(privateKeyFile));
            outFileIn = new BufferedInputStream(new FileInputStream(outFileName));
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }



        decryptFile(outFileIn, keyIn, passPhrase, recoverFile);
    }
}

然后,我的 decryptFile 方法有两部分, 一个是带有二进制内容的 base64 编码, 另一个是主要的解密部分。

public static void decryptFile(InputStream outFileIn, InputStream privKeyStream, char[] passPhrase, String outFileName) {
    // ----- Decrypt the file

    try {

        ByteBuffer buf = ByteBuffer.allocate(1024 * 10);
        byte[] read = new byte[1024];

        while (outFileIn.read(read, 0, 1024) != -1) {
            buf.put(read);
        }

        BASE64Encoder en = new BASE64Encoder();
        String temp = en.encode(buf.array());
        // System.out.println("Temp: " + temp);

        byte[] newB = null;
        BASE64Decoder en1 = new BASE64Decoder();
        try {
            newB = en1.decodeBuffer(temp);
        } catch (Exception e) {
            System.out.println("Exception: " + e);
        }
        ByteArrayInputStream bais = new ByteArrayInputStream(newB);
        decryptIt(bais, privKeyStream, passPhrase, outFileName);

    } catch (Exception e1) {

        e1.printStackTrace();
    }

}

这是最新版 pg Bouncy Castle Cryptography Library 1.58 的完整源代码。

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
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.nio.ByteBuffer;
import java.security.GeneralSecurityException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Iterator;

import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.bcpg.BCPGOutputStream;
import org.bouncycastle.bcpg.HashAlgorithmTags;
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.PGPLiteralDataGenerator;
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.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureGenerator;
import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator;
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator;
import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory;
import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

//
public class FileEncryptTest {
    private static File publicKeyFile = new File("resource/PGP1D0.pkr");
    private static File privateKeyFile = new File("resource/PGP1D0.skr");
    private static String privateKeyPassword = "passphrase";

    private static final boolean isEncrypt = false;


    public static void main(String[] args) {
        Security.addProvider(new BouncyCastleProvider());

        String outFileName = "resource/tile_doc.signed.in";
        String recoverFile = "resource/tile_doc.out";
        OutputStream out = null;
        InputStream keyIn = null;
        InputStream outFileIn = null;
        String fileName = "resource/tile_doc.in";

        PGPPublicKey encKey = null;

        char[] passPhrase = privateKeyPassword.toCharArray();
        boolean armor = false;
        boolean withIntegrityCheck = true;

        if (isEncrypt) {
            try {
                keyIn = new BufferedInputStream(new FileInputStream(privateKeyFile));
                out = new BufferedOutputStream(new FileOutputStream(outFileName));
                encKey = readPublicKeyFromCol(new FileInputStream(publicKeyFile));
                //
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }


                try {
                    signFile(fileName, keyIn, out, passPhrase, armor);

                    out = new BufferedOutputStream(new FileOutputStream(outFileName));

                } catch (GeneralSecurityException | IOException | PGPException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            encryptFile(outFileName, out, fileName, encKey, passPhrase, armor, withIntegrityCheck);
        } else {


            try {
                keyIn = new BufferedInputStream(new FileInputStream(privateKeyFile));
                outFileIn = new BufferedInputStream(new FileInputStream(outFileName));
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }



            decryptFile(outFileIn, keyIn, passPhrase, recoverFile);
        }
    }

    static final KeyFingerPrintCalculator FP_CALC = new BcKeyFingerprintCalculator();

    private static PGPPublicKey readPublicKeyFromCol(InputStream in) throws Exception {
        PGPPublicKeyRing pkRing = null;

        // PGPPublicKeyRingCollection pkCol = new PGPPublicKeyRingCollection(in,
        // FP_CALC);
        PGPPublicKeyRingCollection pkCol = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(in), FP_CALC);
        System.out.println("key ring size=" + pkCol.size());
        Iterator it = pkCol.getKeyRings();
        while (it.hasNext()) {
            pkRing = (PGPPublicKeyRing) it.next();
            Iterator pkIt = pkRing.getPublicKeys();
            while (pkIt.hasNext()) {
                PGPPublicKey key = (PGPPublicKey) pkIt.next();
                System.out.println("Encryption key = " + key.isEncryptionKey() + ", Master key = " + key.isMasterKey());
                if (key.isEncryptionKey())
                    return key;
            }
        }
        return null;
    }

    public static void decryptFile(InputStream outFileIn, InputStream privKeyStream, char[] passPhrase, String outFileName) {
        // ----- Decrypt the file

        try {

            ByteBuffer buf = ByteBuffer.allocate(1024 * 10);
            byte[] read = new byte[1024];

            while (outFileIn.read(read, 0, 1024) != -1) {
                buf.put(read);
            }

            BASE64Encoder en = new BASE64Encoder();
            String temp = en.encode(buf.array());
            // System.out.println("Temp: " + temp);

            byte[] newB = null;
            BASE64Decoder en1 = new BASE64Decoder();
            try {
                newB = en1.decodeBuffer(temp);
            } catch (Exception e) {
                System.out.println("Exception: " + e);
            }
            ByteArrayInputStream bais = new ByteArrayInputStream(newB);
            decryptIt(bais, privKeyStream, passPhrase, outFileName);

        } catch (Exception e1) {

            e1.printStackTrace();
        }

    }


    private static PGPPrivateKey findSecretKey(InputStream keyIn, long keyID, char[] pass)
            throws IOException, PGPException, NoSuchProviderException {
        PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(keyIn), FP_CALC);
        PGPSecretKey pgpSecKey = pgpSec.getSecretKey(keyID);
        if (pgpSecKey == null) {
            return null;
        }
        PBESecretKeyDecryptor secretKeyDecryptor = new JcePBESecretKeyDecryptorBuilder()
                .setProvider(BouncyCastleProvider.PROVIDER_NAME).build(pass);

        return pgpSecKey.extractPrivateKey(secretKeyDecryptor);
    }

    private static void decryptIt(InputStream in, InputStream keyIn, char[] passwd, String filename) throws Exception {
        in = PGPUtil.getDecoderStream(in);
        try {
            PGPObjectFactory pgpF = new PGPObjectFactory(in, FP_CALC);
            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();
                System.out.println("pbe id=" + pbe.getKeyID());
                sKey = findSecretKey(keyIn, pbe.getKeyID(), passwd);
            }
            if (sKey == null) {
                throw new IllegalArgumentException("secret key for message not found.");
            }
            // InputStream clear = pbe.getDataStream(sKey, "BC");
            InputStream clear = pbe.getDataStream(new BcPublicKeyDataDecryptorFactory(sKey));
            PGPObjectFactory plainFact = new PGPObjectFactory(clear, FP_CALC);
            Object message = plainFact.nextObject();
            if (message instanceof PGPCompressedData) {
                PGPCompressedData cData = (PGPCompressedData) message;
                PGPObjectFactory pgpFact = new PGPObjectFactory(cData.getDataStream(), FP_CALC);
                message = pgpFact.nextObject();
            }
            // ByteArrayOutputStream baos = new ByteArrayOutputStream();
            BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(filename));
            if (message instanceof PGPLiteralData) {
                PGPLiteralData ld = (PGPLiteralData) message;
                InputStream unc = ld.getInputStream();
                int ch;
                while ((ch = unc.read()) >= 0) {
                    bout.write(ch);
                }

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

            bout.flush();
            bout.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");
            }
        } catch (PGPException e) {
            System.err.println(e);
            if (e.getUnderlyingException() != null) {
                e.getUnderlyingException().printStackTrace();
            }
        }
    }

    private static void encryptFile(String outFileName, OutputStream out, String fileName, PGPPublicKey encKey,
            char[] passPhrase, boolean armor, boolean withIntegrityCheck) {
        if (armor) {
            out = new ArmoredOutputStream(out);
        }

        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
        System.out.println("creating comData...");
        // get the data from the original file
        PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(PGPCompressedDataGenerator.ZIP);
        try {
            PGPUtil.writeFileToLiteralData(comData.open(bOut), PGPLiteralData.BINARY, new File(fileName));
        } catch (IOException e) {

            e.printStackTrace();
        } finally {
            try {
                comData.close();
            } catch (IOException e) {

            }
        }

        PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(
                new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(withIntegrityCheck)
                        .setSecureRandom(new SecureRandom()).setProvider("BC"));
        encGen.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(encKey).setProvider("BC"));

        byte[] bytes = bOut.toByteArray();
        OutputStream cOut;
        try {
            cOut = encGen.open(out, bytes.length);
            cOut.write(bytes);
        } catch (IOException | PGPException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            try {
                encGen.close();
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

    }

    /**
     * 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.");
    }

    private static void signFile(String fileName, InputStream keyIn, OutputStream out, char[] pass, boolean armor)
            throws GeneralSecurityException, IOException, PGPException {
        if (armor) {
            out = new ArmoredOutputStream(out);
        }

        PGPSecretKey pgpSec = readSecretKey(keyIn);
        PGPPrivateKey pgpPrivKey = pgpSec
                .extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(pass));
        PGPSignatureGenerator sGen = new PGPSignatureGenerator(
                new JcaPGPContentSignerBuilder(pgpSec.getPublicKey().getAlgorithm(), PGPUtil.SHA1).setProvider("BC"));

        sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);

        BCPGOutputStream bOut = new BCPGOutputStream(out);

        InputStream fIn = new BufferedInputStream(new FileInputStream(fileName));

        byte[] buf = new byte[1024];
        int len;
        while ((len = fIn.read(buf)) > 0) {
            sGen.update(buf, 0, len);
        }

        //int ch;
        //while ((ch = fIn.read()) >= 0) {
        //  sGen.update((byte) ch);
        //}

        fIn.close();

        sGen.generate().encode(bOut);

        if (armor) {
            out.close();
        }

        out.close();
        bOut.close();
    }
}

最后,public/private 密钥文件生成为 rsa。 我从RSAKeyPairGenerator.java.

那里借用了代码

来源如下

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.security.SignatureException;
import java.util.Date;

import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.bcpg.HashAlgorithmTags;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPEncryptedData;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPKeyPair;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.operator.PGPDigestCalculator;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair;
import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder;

public class FileEncDec {

    private static File publicKeyFile = new File("resource/PGP1D0.pkr");
    private static File privateKeyFile = new File("resource/PGP1D0.skr");
    private static String privateKeyPassword = "passphrase";
    private static String identity = "tommybee";
    private static boolean isAll = true;

    private static void exportKeyPair(OutputStream secretOut, OutputStream publicOut, KeyPair pair, String identity,
            char[] passPhrase, boolean armor)
            throws IOException, InvalidKeyException, NoSuchProviderException, SignatureException, PGPException {
        if (armor) {
            secretOut = new ArmoredOutputStream(secretOut);
        }

        PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA1);
        PGPKeyPair keyPair = new JcaPGPKeyPair(PGPPublicKey.RSA_GENERAL, pair, new Date());
        PGPSecretKey secretKey = new PGPSecretKey(PGPSignature.DEFAULT_CERTIFICATION, keyPair, identity, sha1Calc, null,
                null, new JcaPGPContentSignerBuilder(keyPair.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1),
                new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.CAST5, sha1Calc).setProvider("BC")
                        .build(passPhrase));

        secretKey.encode(secretOut);

        secretOut.close();

        if (armor) {
            publicOut = new ArmoredOutputStream(publicOut);
        }

        PGPPublicKey key = secretKey.getPublicKey();

        key.encode(publicOut);

        publicOut.close();
    }

    public static void main(String[] args) throws Exception {
        Security.addProvider(new BouncyCastleProvider());

        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC");

        kpg.initialize(1024);

        KeyPair kp = kpg.generateKeyPair();

        if (isAll) {

            FileOutputStream out1 = new FileOutputStream(privateKeyFile);
            FileOutputStream out2 = new FileOutputStream(publicKeyFile);

            exportKeyPair(out1, out2, kp, identity, privateKeyPassword.toCharArray(), true);
        } else {
            FileOutputStream out1 = new FileOutputStream(privateKeyFile);
            FileOutputStream out2 = new FileOutputStream(publicKeyFile);

            exportKeyPair(out1, out2, kp, identity, privateKeyPassword.toCharArray(), false);
        }
    }

}

希望对您有所帮助。 此致,