Pgp sign + encrypt然后解密+验证

时间:2017-09-07 06:52:33

标签: java encryption bouncycastle sign pgp

在使用sign encrypt进行解密和验证时,我会在验证时继续在流中获取未知对象。消息完整性检查已通过,但是当我在解密后尝试在下一行验证时,我收到了上述错误。

    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进行签名,然后使用encrypt方法加密文件。

1 个答案:

答案 0 :(得分:3)

我已经测试了您的代码

加密&签署了我的一些文本文件,然后将其解密。

然后我在解密时也收到了错误消息。

消息是 -

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可能与代码的某些部分不同。

我在主要方法中添加了所有内容。

首先,我的私人&公钥文件声明。

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

Sign&当 isEncrypt 为true时加密文件,否则解密文件。 当isEncrypt标志为true时,在使用加密进行签名后,原始文件为tile_doc.in和tile_doc.signed.in,然后将该标志设置为false并运行。 您可以在资源文件夹中看到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();
    }
}

最后,使用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);
        }
    }

}

我希望这会对你有所帮助。 的问候,