简体   繁体   English

Pgp sign + encrypt然后解密+验证

[英]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. 首先我使用signFile签名,然后使用encrypt方法加密文件。

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, 我不确定与你的相同的消息,但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();
}

My bouncycastle library is exactly bcpg-jdk15on-158.jar - the latest one. 我的bouncycastle库正好是bcpg-jdk15on-158.jar - 最新的。 So, API might be different some part of code. 因此,API可能与代码的某些部分不同。

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

Then, my decryptFile method have two parts, one is a base64 encoding with binary contents, another is a main decryption part. 然后,我的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();
    }

}

This is full source code with latest version of pg Bouncy Castle Cryptography Library 1.58. 这是最新版本的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. 最后,使用rsa生成公钥/私钥文件。 I borrowed the code from RSAKeyPairGenerator.java. 我从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, 问候,

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 PGP/GPG PHP 加密签名(使用 GnuPG)和 Java 解密验证(使用 Bouncy Castle) - PGP/GPG PHP encrypt-sign (using GnuPG) and Java decrypt-verify (using Bouncy Castle) Bouncycastle PGP 解密和验证 - Bouncycastle PGP decrypt and verify Bouncy Castle PGP标志和加密一次通过? - Bouncy Castle PGP sign and encrypt in one pass? 我可以在没有Bouncy Castle的情况下使用PKCS#7加密,解密,签名或验证数据吗? - Can I encrypt, decrypt, sign or verify data using PKCS#7 without Bouncy Castle? 在 JAVA 中使用 Bouncy Castle PGP 加密/解密文件 - Encrypt/Decrypt Files Using Bouncy Castle PGP in JAVA RSA和AES,用于加密和解密plainText(验证密钥) - RSA and AES for encrypt and decrypt a plainText (verify key) 带HSM的“ pgp_sym_encrypt”和“ pgp_sym_decrypt”机制(硬件安全模块) - ‘pgp_sym_encrypt’ and ‘pgp_sym_decrypt’ mechanism with HSM (hardware security module) 我一直在使用 Bouncy Castle API 为 byte[] 进行 PGP 加密和解密,并收到“Invalid Armor”错误消息 - I have been working on PGP Encrypt and Decrypt for byte[] with Bouncy Castle API and getting "Invalid Armor" error message PGP,验证证书上的签名 - PGP, verify signature on a certificate 使用PGP加密文件的水壶 - Kettle to encrypt file using PGP
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM