关于PGP解密基于Java Bouncy Castle

第一次了解PGP,查了好多资料费时1天半算是完成了,特此记录一下,也是我第一篇文章。

前期工作
首先要找一个秘钥和公钥。
个人是在这个网址上获取的 https://pgpkeygen.com/

然后请到oracle官网下载Java密码术扩展(JCE)无限强度管辖权政策文件
http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
请根据个人jdk自行找版本,下载后的2个文件
放到你jre目录下的lib / security目录下 下载后放到你jre目录下的lib / security目录下

完成以上工作后就准备加密解密吧
先在pom上把这段copy上去

<dependency>
  <groupId>org.bouncycastle</groupId>
  <artifactId>bcpg-jdk15on</artifactId>
  <version>1.50</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on -->
<dependency>
  <groupId>org.bouncycastle</groupId>
  <artifactId>bcprov-jdk15on</artifactId>
  <version>1.50</version>
  </dependency>

想自己下载也是可以的
http://www.bouncycastle.org/latest_releases.html


下面就是我使用的代码 并非原创 拿来借鉴的 不用于任何商业用途不做任何盈利活动
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.util.Iterator;

import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.openpgp.PGPCompressedData;
import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
import org.bouncycastle.openpgp.PGPEncryptedData;
import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
import org.bouncycastle.openpgp.PGPEncryptedDataList;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPLiteralData;
import org.bouncycastle.openpgp.PGPObjectFactory;
import org.bouncycastle.openpgp.PGPOnePassSignatureList;
import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData;
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;
import org.bouncycastle.util.io.Streams;

public class KeyBasedLargeFileProcessor
{

public static void decryptFile(
        String inputFileName,
        String keyFileName,
        char[] passwd,
        String defaultFileName)
        throws IOException, NoSuchProviderException
{
    InputStream in = new BufferedInputStream(new FileInputStream(inputFileName));
    InputStream keyIn = new BufferedInputStream(new FileInputStream(keyFileName));
     decryptFile(in, keyIn, passwd, defaultFileName);
    keyIn.close();
    in.close();
  }
   
/**
 * decrypt the passed in message stream
 */

public static void decryptFile(
        InputStream in,
        InputStream keyIn,
        char[]      passwd,
        String      defaultFileName)
        throws IOException, NoSuchProviderException
{
      in = PGPUtil.getDecoderStream(in);
    try
    {
        PGPObjectFactory        pgpF = new PGPObjectFactory(in);
        PGPEncryptedDataList    enc;

        Object                  o = pgpF.nextObject();
        //
        // the first object might be a PGP marker packet.
        //
        if (o instanceof PGPEncryptedDataList)
        {
            enc = (PGPEncryptedDataList)o;
        }
        else
        {
            enc = (PGPEncryptedDataList)pgpF.nextObject();
        }

        //
        // find the secret key
        //
        Iterator                    it = enc.getEncryptedDataObjects();
        PGPPrivateKey               sKey = null;
        PGPPublicKeyEncryptedData   pbe = null;
        PGPSecretKeyRingCollection  pgpSec = new PGPSecretKeyRingCollection(
                PGPUtil.getDecoderStream(keyIn));

        while (sKey == null && it.hasNext())
        {
            pbe = (PGPPublicKeyEncryptedData)it.next();

            sKey = PGPExampleUtil.findSecretKey(pgpSec, pbe.getKeyID(), passwd);

        }

        if (sKey == null)
        {
            throw new IllegalArgumentException("secret key for message not found.");
        }

        InputStream         clear = pbe.getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider("BC").build(sKey));

        PGPObjectFactory    plainFact = new PGPObjectFactory(clear);

        PGPCompressedData   cData = (PGPCompressedData)plainFact.nextObject();

        InputStream         compressedStream = new BufferedInputStream(cData.getDataStream());
        PGPObjectFactory    pgpFact = new PGPObjectFactory(compressedStream);

        Object              message = pgpFact.nextObject();

        if (message instanceof PGPLiteralData)
        {
            PGPLiteralData ld = (PGPLiteralData)message;

            String outFileName = ld.getFileName();
            if (outFileName.length() == 0)
            {
                outFileName = defaultFileName;
            }

            InputStream unc = ld.getInputStream();
            OutputStream fOut =  new BufferedOutputStream(new FileOutputStream(outFileName));

            Streams.pipeAll(unc, fOut);

            fOut.close();
        }
        else if (message instanceof PGPOnePassSignatureList)
        {
            throw new PGPException("encrypted message contains a signed message - not literal data.");
        }
        else
        {
            throw new PGPException("message is not a simple encrypted file - type unknown.");
        }

        if (pbe.isIntegrityProtected())
        {
            if (!pbe.verify())
            {
                System.err.println("message failed integrity check");
            }
            else
            {
                System.err.println("message integrity check passed");
            }
        }
        else
        {
            System.err.println("no message integrity check");
        }
    }
    catch (PGPException e)
    {
        System.err.println(e);
        if (e.getUnderlyingException() != null)
        {
            e.getUnderlyingException().printStackTrace();
        }
    }
}

public static void encryptFile(
        String          outputFileName,
        String          inputFileName,
        String          encKeyFileName,
        boolean         armor,
        boolean         withIntegrityCheck)
        throws IOException, NoSuchProviderException, PGPException
{
    OutputStream out = new BufferedOutputStream(new FileOutputStream(outputFileName));
    PGPPublicKey encKey = PGPExampleUtil.readPublicKey(encKeyFileName);
    encryptFile(out, inputFileName, encKey, armor, withIntegrityCheck);
    out.close();
}

public static void encryptFile(
        OutputStream    out,
        String          fileName,
        PGPPublicKey    encKey,
        boolean         armor,
        boolean         withIntegrityCheck)
        throws IOException, NoSuchProviderException
{
    if (armor)
    {
        out = new ArmoredOutputStream(out);
    }

    try
    {
        PGPEncryptedDataGenerator   cPk = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(withIntegrityCheck).setSecureRandom(new SecureRandom()).setProvider("BC"));

        cPk.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(encKey).setProvider("BC"));

        OutputStream                cOut = cPk.open(out, new byte[1 << 16]);

        PGPCompressedDataGenerator  comData = new PGPCompressedDataGenerator(
                PGPCompressedData.ZIP);

        PGPUtil.writeFileToLiteralData(comData.open(cOut), PGPLiteralData.BINARY, new File(fileName), new byte[1 << 16]);

        comData.close();

        cOut.close();

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

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.NoSuchProviderException;
import java.util.Iterator;

import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPLiteralData;
import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPPublicKey;
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.PGPUtil;
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder;
import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider;

class PGPExampleUtil
{

static byte[] compressFile(String fileName, int algorithm) throws IOException
{
   ByteArrayOutputStream bOut = new ByteArrayOutputStream();
    PGPCompressedDataGenerator comData = new 
    PGPCompressedDataGenerator(algorithm);
    PGPUtil.writeFileToLiteralData(comData.open(bOut), PGPLiteralData.BINARY,
            new File(fileName));
    comData.close();
    return bOut.toByteArray();
}

/**
 * Search a secret key ring collection for a secret key corresponding to keyID if it
 * exists.
 *
 * @param pgpSec a secret key ring collection.
 * @param keyID keyID we want.
 * @param pass passphrase to decrypt secret key with.
 * @return
 * @throws PGPException
 * @throws NoSuchProviderException
 */
static PGPPrivateKey findSecretKey(PGPSecretKeyRingCollection pgpSec, long keyID, char[] pass)
        throws PGPException, NoSuchProviderException
{

    PGPSecretKey pgpSecKey = pgpSec.getSecretKey(keyID);
    if (pgpSecKey == null)
    {
        return null;
    }
    PBESecretKeyDecryptor decryptor = new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass);
    return pgpSecKey.extractPrivateKey(decryptor);
}

static PGPPublicKey readPublicKey(String fileName) throws IOException, PGPException
{
    InputStream keyIn = new BufferedInputStream(new FileInputStream(fileName));
    PGPPublicKey pubKey = readPublicKey(keyIn);
    keyIn.close();
    return pubKey;
}

/**
 * A simple routine that opens a key ring file and loads the first available key
 * suitable for encryption.
 *
 * @param input
 * @return
 * @throws IOException
 * @throws PGPException
 */
static PGPPublicKey readPublicKey(InputStream input) throws IOException, PGPException
{
    PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(
            PGPUtil.getDecoderStream(input));

    //
    // 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 = pgpPub.getKeyRings();
    while (keyRingIter.hasNext())
    {
        PGPPublicKeyRing keyRing = (PGPPublicKeyRing)keyRingIter.next();

        Iterator keyIter = keyRing.getPublicKeys();
        while (keyIter.hasNext())
        {
            PGPPublicKey key = (PGPPublicKey)keyIter.next();

            if (key.isEncryptionKey())
            {
                return key;
            }
        }
    }

    throw new IllegalArgumentException("Can't find encryption key in key ring.");
}

static PGPSecretKey readSecretKey(String fileName) throws IOException, PGPException
{
    InputStream keyIn = new BufferedInputStream(new FileInputStream(fileName));
    PGPSecretKey secKey = readSecretKey(keyIn);
    keyIn.close();
    return secKey;
}

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

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

写一个main方法测试一下吧

public static void main(
        String[] args)
        throws Exception
{
    Security.addProvider(new BouncyCastleProvider());
   //加密方法
    encryptFile(需要加密的文件路径+需要加密的加密文件名称,加密后生成文件路径+生成加密文件名称","公钥",true,true);
   //解密方法
    decryptFile(加密文件路径+加密文件名称, 私钥, "密码".toCharArray(), 解密后文件存放路径+解密后文件名称);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值