openPGP加密解密

news/2024/7/1 5:18:09

首先请大家一定要搞清楚加密解密概念:
下面这是百度出来的。
如果只是单方面采用非对称性加密算法,其实有两种方式,用于不同用处.

  1. 第一种是签名,使用私钥加密,公钥解密,用于让所有公钥所有者验证私钥所有者的身份并且用来防止私钥所有者发布的内容被篡改.但是不用来保证内容不被他人获得.

  2. 第二种是加密,用公钥加密,私钥解密,用于向公钥所有者发布信息,这个信息可能被他人篡改,但是无法被他人获得.

如果甲想给乙发一个安全的保密的数据,那么应该甲乙各自有一个私钥,甲先用乙的公钥加密这段数据,再用自己的私钥加密这段加密后的数据.最后再发给乙,这样确保了内容即不会被读取,也不会被篡改.

折磨了我一个星期,就是因为配合的同事跟我说用公钥解密,所以一定要搞清楚概念。

代码块:
KeyBasedLargeFileProcessor.java

import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.*;
import org.bouncycastle.openpgp.bc.BcPGPObjectFactory;
import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory;
import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
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;import java.io.*;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Iterator;/*
* 加密与解密
* */public class KeyBasedLargeFileProcessor {/** 解密*  @Para inputFileName  输入的文件路径*  @Para keyFileName  私钥文件路径*   @Para passwd  私钥密码*   @Para defaultFileName  输出文件路径* */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();}public static void decryptFile(InputStream in,InputStream keyIn,char[] passwd,String defaultFileName)throws IOException, NoSuchProviderException {in = PGPUtil.getDecoderStream(in);try {//创建PGP对象JcaPGPObjectFactory pgpF = new JcaPGPObjectFactory(in);//PGP加密的数据列表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),new JcaKeyFingerprintCalculator());System.out.println("pgpSec=" + pgpSec);while (sKey == null && it.hasNext()) {pbe = (PGPPublicKeyEncryptedData) it.next();System.out.println("pbe=" + pbe);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 JcaPGPObjectFactory(clear);//压缩解密对象PGPCompressedData cData = (PGPCompressedData) plainFact.nextObject();//获得压缩对象流InputStream compressedStream = new BufferedInputStream(cData.getDataStream());PGPObjectFactory pgpFact = new BcPGPObjectFactory(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();}}}/**  加密*  @Para outputFileName  输出文件的路径*  @Para inputFileName   输入文件的路径*  @Para encKeyFileName  公钥*  @Para armor*  @Para withIntegrityCheck 完整性检查* */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();}}}public static void main(String[] args)throws Exception {Security.addProvider(new BouncyCastleProvider());//encryptFile("D://1.PGP.tmp","D://123.txt","D://kkprivate.asc",true,true);decryptFile("D://104110082202643_ODD_02_20191227.PGP", "D://kkprivate.asc", "67216688".toCharArray(), "D://104110082202643_ODD_02_20191227.txt");}
}

PGPExampleUtil.java

package org.kxsj.com.pgp;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.*;
import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory;
import org.bouncycastle.openpgp.jcajce.JcaPGPPublicKeyRingCollection;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;import java.io.*;
import java.security.GeneralSecurityException;
import java.security.NoSuchProviderException;
import java.util.Iterator;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{PGPSecretKey pgpSecKey = pgpSec.getSecretKey(keyID);if (pgpSecKey == null){return null;}PGPPrivateKey bc = pgpSecKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(pass));return bc;}/** 读取公钥* @Para  文件路径* */static PGPPublicKey readPublicKey(String fileName) throws IOException, PGPException{//文件InputStream keyIn = new BufferedInputStream(new FileInputStream(fileName));//字节//ByteArrayInputStream keyIn = new ByteArrayInputStream(fileName.getBytes());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{// JcaPGPObjectFactory pgpPub = new JcaPGPObjectFactory(PGPUtil.getDecoderStream(input));//PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(input),new KeyFingerPrintCalculator());JcaPGPPublicKeyRingCollection jcaPgpPub =new JcaPGPPublicKeyRingCollection(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 = jcaPgpPub.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{JcaPGPPublicKeyRingCollection pgpSec = new JcaPGPPublicKeyRingCollection(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.");}/*** verify the signature in in against the file fileName.*/private boolean verifySignature(String fileName, byte[] b, InputStream keyIn) throws GeneralSecurityException, IOException, PGPException {//in = PGPUtil.getDecoderStream(in);PGPObjectFactory pgpFact = new JcaPGPObjectFactory(b);PGPSignatureList p3 = null;Object o = pgpFact.nextObject();if (o instanceof PGPCompressedData) {PGPCompressedData c1 = (PGPCompressedData) o;pgpFact = new JcaPGPObjectFactory(c1.getDataStream());p3 = (PGPSignatureList) pgpFact.nextObject();} else {p3 = (PGPSignatureList) o;}JcaPGPPublicKeyRingCollection pgpPubRingCollection = new JcaPGPPublicKeyRingCollection(PGPUtil.getDecoderStream(keyIn));InputStream dIn = new BufferedInputStream(new FileInputStream(fileName));PGPSignature sig = p3.get(0);PGPPublicKey key = pgpPubRingCollection.getPublicKey(sig.getKeyID());sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider(new BouncyCastleProvider()), key);int ch;while ((ch = dIn.read()) >= 0) {sig.update((byte) ch);}dIn.close();if (sig.verify()) {return true;} else {return false;}}private byte[] createSignature(String fileName, InputStream keyIn, char[] pass, boolean armor) throws GeneralSecurityException, IOException, PGPException {PGPSecretKey pgpSecKey = readSecretKey(keyIn);PGPPrivateKey pgpPrivKey = pgpSecKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider(new BouncyCastleProvider()).build(pass));PGPSignatureGenerator sGen = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(pgpSecKey.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1).setProvider(new BouncyCastleProvider()));sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);ByteArrayOutputStream byteOut = new ByteArrayOutputStream();ArmoredOutputStream aOut = new ArmoredOutputStream(byteOut);BCPGOutputStream bOut = new BCPGOutputStream(byteOut);InputStream fIn = new BufferedInputStream(new FileInputStream(fileName));int ch;while ((ch = fIn.read()) >= 0) {sGen.update((byte) ch);}aOut.endClearText();fIn.close();sGen.generate().encode(bOut);if (armor) {aOut.close();}return byteOut.toByteArray();}}

maven依赖:

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

JDK默认Policy只能支持<=128位Key,GPG的密钥从1024-2048,所以必须扩展该Policy。需要下载jce的安全策略文件,去jre路径下C:\Program Files\Java\jdk1.8.0_241\jre\lib\security\policy覆盖。


http://lihuaxi.xjx100.cn/news/236602.html

相关文章

MakeCode图形化编程语言学习笔记:micro:bit编程练习题[图]

2019独角兽企业重金招聘Python工程师标准>>> MakeCode图形化编程语言学习笔记&#xff1a;micro:bit编程练习题[图]&#xff1a; 基础训练题&#xff1a; Q1&#xff1a;摇晃micro:bit编程板&#xff0c;随机出现7个小动物图标中的一个&#xff0c;并且前后相邻两次…

011:视图函数介绍

视图&#xff1a; 视图一般都写在 app 的 views.py 中。并且视图的第一个参数永远都是 request &#xff08;一个HttpRequest&#xff09;对象。这个对象存储了请求过来的所有信息&#xff0c;包括携带的参数以及一些头部信息等。在视图中&#xff0c;一般是完成逻辑相关的操作…

java设计一个bank类实现银行_SAP银企直连之平安银行(ECC版)

关于讲解SAP中国本地化银企直连系统功能&#xff0c;它通过ECC和S4 HANA 1909两个不同版本的演示来讲解银企直连付款相关功能实施和应用&#xff0c;有兴趣的可以联系微信号&#xff1a;timijia进行付费获取。以下资料仅供大家参考&#xff1a;说明&#xff1a;因为平安银行较S…

传承乡邦文化,展示国学之美,联墨香飘远,文明花放红;

2019独角兽企业重金招聘Python工程师标准>>> 12月16日上午&#xff0c;阳光普照&#xff0c;翰墨飘香。由揭阳市文联指导、揭阳市楹联学会主办、榕城区图书馆协办的“我们的美好生活”原创联墨作品展在榕城区图书馆隆重开幕。 此次活动意在传承乡邦文化&#xff0c;…

Windows和Linux的编译理解

Windows一般编译出来的x86的软件&#xff0c;就是只能在x86的系统上才能运行&#xff0c;同理&#xff0c;在x64系统上也是一样的道理。 Linux利用gcc编译器编译&#xff0c;可以在Linux上面运行&#xff0c;但是想要在嵌入式系统上运行的话&#xff0c;需要在Linux上安装相应的…

定义一个属性_Python property属性

1. 什么是property属性一种用起来像是使用的实例属性一样的特殊属性&#xff0c;可以对应于某个方法# ############### 定义 ###############class Foo: def func(self): pass # 定义property属性 property def prop(self): pass# ############### 调用 ###############foo_obj…

Android 中一些常用类的常用方法(Math、Random、Color、Paint、Canvas、Bitmap、BitmapFactory)...

1.java.lang.Math类常用的常量和方法&#xff1a; Math.PI 记录的圆周率 Math.E 记录e的常量 Math.abs 求绝对值 Math.sin 正弦函数 Math.asin 反正弦函数 Math.cos 余弦函数 Math.acos 反余弦函数 Math.tan 正切函数 Math.atan 反正切函数 Math.atan2 商的反正切函数 Math.toD…

hdu 1724 Ellipse——辛普森积分

题目&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid1724 #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define db double using namespace std; const db eps1e-5; int T;db a,b,l,r; db f(db x){return sqrt(…