简体   繁体   中英

Pgp sign+encrypt then decrypt+verify

While going with sign encrypt then decrypt and verify, I keep getting unknown object in stream while verifying. Message integrity check passed but when I try to verify in the very next line after decrypt I'm getting the above said error.

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

First I sign using signFile and then I encrypt the file using encrypt method.

I've tested your code

Encrypt & signed some of my text file then decrypt it back.

then I've also got a error message when decryption.

The message was -

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)

I am not sure the same message with yours, but the signFile method must be looks like as follows,

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

My bouncycastle library is exactly bcpg-jdk15on-158.jar - the latest one. So, API might be different some part of code.

I added it all in my main method.

First, my private & public key file declaration.

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

Sign & encrypt a file when the isEncrypt is true, otherwise decrypt the file. The original file is tile_doc.in and tile_doc.signed.in after signing with encryption when the isEncrypt flag is true, Then let the flag to false and run. You can see the tile_doc.out file in the resource folder.

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

Then, my decryptFile method have two parts, one is a base64 encoding with binary contents, another is a main decryption part.

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

}

This is full source code with latest version of 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();
    }
}

Finally, the public/private key file generate with rsa. I borrowed the code from RSAKeyPairGenerator.java.

The source as follows

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

}

I hope this helps you. Regards,

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM