首先:介绍一下PGP是啥:

1991年, 一个叫Phil_Zimmermann的程序员, 为了传输加密报文, 开发的一款加密软件,:pgp, 但是它是商用程序, 后来自由软件觉得好用, 开发了一个开源版本: gnuPG, 后来呢, 又出现了一个标准的pgp开源软件: openpgp, gnuPG可以加密解密另外两个软件的输出

https://www.goanywhere.com/blog/2013/07/18/openpgp-pgp-gpg-difference

java使用pgp:

<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcpg-jdk15on -->
<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>
package com.xx.util.encrypt;import java.io.*;
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.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.PGPSignatureList;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;public class PgpUtils {private static PgpUtils INSTANCE = null;public static PgpUtils getInstance() {if (INSTANCE == null) INSTANCE = new PgpUtils();return INSTANCE;}private PgpUtils() {}private PGPPublicKey readPublicKey(InputStream in) throws IOException, PGPException {in = org.bouncycastle.openpgp.PGPUtil.getDecoderStream(in);PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(in);//// 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.//PGPPublicKey key = null;//// iterate through the key rings.//Iterator<PGPPublicKeyRing> rIt = pgpPub.getKeyRings();while (key == null && rIt.hasNext()) {PGPPublicKeyRing kRing = rIt.next();Iterator<PGPPublicKey> kIt = kRing.getPublicKeys();while (key == null && kIt.hasNext()) {PGPPublicKey k = kIt.next();if (k.isEncryptionKey()) {key = k;}}}if (key == null) {throw new IllegalArgumentException("Can't find encryption key in key ring.");}return key;}/*** Load a secret key ring collection from keyIn and find the secret key corresponding to* keyID if it exists.** @param keyIn input stream representing a key ring collection.* @param keyID keyID we want.* @param pass  passphrase to decrypt secret key with.** @return** @throws IOException* @throws PGPException* @throws NoSuchProviderException*/private PGPPrivateKey findSecretKey(InputStream keyIn, long keyID, char[] pass) throws IOException, PGPException, NoSuchProviderException {PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(org.bouncycastle.openpgp.PGPUtil.getDecoderStream(keyIn));PGPSecretKey pgpSecKey = pgpSec.getSecretKey(keyID);if (pgpSecKey == null) {return null;}PBESecretKeyDecryptor a = new JcePBESecretKeyDecryptorBuilder(new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build()).setProvider("BC").build(pass);return pgpSecKey.extractPrivateKey(a);}/*** decrypt the passed in message stream*/private void decryptFile(InputStream in, OutputStream out, InputStream keyIn, char[] passwd) throws Exception {Security.addProvider(new BouncyCastleProvider());in = org.bouncycastle.openpgp.PGPUtil.getDecoderStream(in);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<PGPPublicKeyEncryptedData> it = enc.getEncryptedDataObjects();PGPPrivateKey sKey = null;PGPPublicKeyEncryptedData pbe = null;while (sKey == null && it.hasNext()) {pbe = it.next();sKey = findSecretKey(keyIn, pbe.getKeyID(), passwd);}if (sKey == null) {throw new IllegalArgumentException("Secret key for message not found.");}PublicKeyDataDecryptorFactory b = new JcePublicKeyDataDecryptorFactoryBuilder().setProvider("BC").setContentProvider("BC").build(sKey);InputStream clear = pbe.getDataStream(b);PGPObjectFactory plainFact = new PGPObjectFactory(clear);Object message = plainFact.nextObject();if (message instanceof PGPCompressedData) {PGPCompressedData cData = (PGPCompressedData) message;PGPObjectFactory pgpFact = new PGPObjectFactory(cData.getDataStream());message = pgpFact.nextObject();}if (message instanceof PGPLiteralData) {PGPLiteralData ld = (PGPLiteralData) message;InputStream unc = ld.getInputStream();int ch;while ((ch = unc.read()) >= 0) {out.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.");}if (pbe.isIntegrityProtected()) {if (!pbe.verify()) {throw new PGPException("Message failed integrity check");}}}private void encryptFile(OutputStream out, String fileName, PGPPublicKey encKey, boolean armor, boolean withIntegrityCheck) throws IOException, NoSuchProviderException, PGPException {Security.addProvider(new BouncyCastleProvider());if (armor) {out = new ArmoredOutputStream(out);}ByteArrayOutputStream bOut = new ByteArrayOutputStream();PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(PGPCompressedData.ZIP);org.bouncycastle.openpgp.PGPUtil.writeFileToLiteralData(comData.open(bOut), PGPLiteralData.BINARY, new File(fileName));comData.close();JcePGPDataEncryptorBuilder c = new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(withIntegrityCheck).setSecureRandom(new SecureRandom()).setProvider("BC");PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(c);JcePublicKeyKeyEncryptionMethodGenerator d = new JcePublicKeyKeyEncryptionMethodGenerator(encKey).setProvider(new BouncyCastleProvider()).setSecureRandom(new SecureRandom());cPk.addMethod(d);byte[] bytes = bOut.toByteArray();OutputStream cOut = cPk.open(out, bytes.length);cOut.write(bytes);cOut.close();out.close();}private byte[] inputStreamToByteArray(InputStream is) throws IOException {ByteArrayOutputStream buffer = new ByteArrayOutputStream();int nRead;byte[] data = new byte[1024];while ((nRead = is.read(data, 0, data.length)) != -1) {buffer.write(data, 0, nRead);}buffer.flush();return buffer.toByteArray();}/*** 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 PGPObjectFactory(b);PGPSignatureList p3 = null;Object o = pgpFact.nextObject();if (o instanceof PGPCompressedData) {PGPCompressedData c1 = (PGPCompressedData) o;pgpFact = new PGPObjectFactory(c1.getDataStream());p3 = (PGPSignatureList) pgpFact.nextObject();} else {p3 = (PGPSignatureList) o;}PGPPublicKeyRingCollection pgpPubRingCollection = new PGPPublicKeyRingCollection(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 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.");}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();}/*** 生成签名文件** @param filePath         签名文件路径* @param privateKeyPath   私钥路径* @param outFilePath      输出证书路径*                         证书名称必须与签名文件名称一样 多后缀: .asc*                         比如: 签名文件为:di.ova   那么生成的证书必须为: di.ova.asc* @param passWord         证书密码* @return 证书字节数组*/public static byte[] signatureCreate(String filePath, String privateKeyPath, String outFilePath, String passWord) {try {FileInputStream privKeyIn = new FileInputStream(privateKeyPath);FileOutputStream signatureOut = new FileOutputStream(outFilePath);byte[] sig = PgpUtils.getInstance().createSignature(filePath, privKeyIn, passWord.toCharArray(), true);signatureOut.write(sig);signatureOut.flush();signatureOut.close();privKeyIn.close();return sig;} catch (Exception e) {e.printStackTrace();return null;}}/*** 签名验证** @param filePath        被签名的文件路径* @param publicKeyPath   公钥路径* @param signFilePath    签名文件路径* @return 是否通过*/public static boolean verifySignature(String filePath, String publicKeyPath, String signFilePath) {try {FileInputStream pubKeyIs = new FileInputStream(publicKeyPath);FileInputStream signFile = new FileInputStream(signFilePath);byte[] signFileBytes = new byte[signFile.available()];signFile.read(signFileBytes);final boolean verifyResult = PgpUtils.getInstance().verifySignature(filePath, signFileBytes, pubKeyIs);signFile.close();pubKeyIs.close();return verifyResult;} catch (Exception e) {e.printStackTrace();return false;}}}

使用签名生成与签名校验方法, 即可对文件进行签名和验签

JAVA使用PGP对文件签名+验签相关推荐

  1. 密码技术应用--SM2文件签名验签

    记录一下对一些稍大文件进行SM2签名验签的实现,这里只列出了核心代码,其他不涉及的代码或者有任何疑问可以查看我之前写的密码技术专题博客 /* 函数名: sm2Signsm2 签名算法实现对文件的签名 ...

  2. 密码技术应用--RSA文件签名验签

    记录一下对一些稍大文件进行RSA签名验签的实现,这里只列出了核心代码,其他不涉及的代码或者有任何疑问可以查看我之前写的密码技术专题博客 /* 函数名: rsaSignrsa 签名算法实现对文件的签名 ...

  3. RSA密钥生成、加密解密、数据签名验签

    公钥.私钥生成 准备工作,基础的帮助类 使用java代码生成公钥私钥 使用openssl生成公钥私钥 加解密 数据签名及验签 数据加解密及签名验签测试 注意项 公钥.私钥生成 准备工作,基础的帮助类 ...

  4. Java 实现 RSA 非对称加密算法-加解密和签名验签

    1. 非对称加密算法简介 非对称加密算法又称现代加密算法,是计算机通信安全的基石,保证了加密数据不会被破解.与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(publickey)和私有密(pr ...

  5. Windows gmssl生成SM2证书 + java bc库签名验签

    Windows gmssl生成SM2证书 + java bc库签名验签 openssl生成SM2证书 1 生成密钥 gmssl ecparam -genkey -name sm2p256v1 -tex ...

  6. 【可食用】KeyTool生成KeyStore,证书、公钥、私钥文档JAVA生成,JAVA实现ECC签名验签

    KeyTool生成KeyStore,证书.公钥.私钥文档JAVA生成,JAVA实现ECC签名验签 一.首先我们可以写个工具类生成密钥对.证书.公钥.私钥文本 jksAndCerGenerator.ja ...

  7. java 国密p7验签_go/Java 国密sm2签名验签

    近期go项目对接第三方Java服务,第三方要求使用国密sm3/sm2算法进行数据签名验签,特记录go端开发注意事项 1 关于密钥对 密钥生成可以使用openssl库,openssl版本至少是1.1.1 ...

  8. Java 实现RSA 签名/验签与加密解密

    文章目录 一.前言 二.签名与验签 1.程序代码如下: 2.程序运行结果: 三.加密解密 1.添加加解密方法 2.程序运行结果 一.前言 RSA 算法相比于AES算法不同的是RSA的秘钥为不同的两个一 ...

  9. js rsa验签_js rsa sign使用笔记(加密,解密,签名,验签)

    你将会收获: js如何加密, 解密 js如何签名, 验签 js和Java交互如何相互解密, 验签(重点) 通过谷歌, 发现jsrsasign库使用者较多. 查看api发现这个库功能很健全. 本文使用方 ...

最新文章

  1. visual studio内置“iis”组件提取及二次开发
  2. Hadoop 单机版和伪分布式版安装
  3. 【ARM】一步一步移植Linux Kernel 2.6.13到板子
  4. js javascript UTF-8 GB2312编码转换
  5. 真香系列-JSFinder实用改造
  6. Java教程:Java定义字符串(2种方式)
  7. python使用-Python 应该怎么去练习和使用?
  8. asp.net mvc在Model中控制日期格式
  9. Cufon中文字符无法识别的解决方案
  10. 全球及中国锗行业发展规模与前景调查分析报告2022-2028年
  11. Mifare 1卡(M1卡、IC卡)读写操作及工作原理整理
  12. webrtc整体框架
  13. 批量将不同文件夹目录中的文件统一提取到同一个文件夹中
  14. win7设置视力保护色
  15. 因特尔显卡自定义分辨率_如何在新版英特尔核芯显卡控制面板中自定义显示器分辨率...
  16. 服务器连接异常系统无法登录,Win10系统电脑无法登录LOL提示服务器连接异常的原因及解决方法...
  17. Centos 7系统常用指令
  18. 微信小程序canvas上传PHP,微信小程序画布 canvas
  19. Image Signal Processing(ISP)-第二章-Demosaic去马赛克以及BMP软件实现
  20. 杭电OJ 1129(C++)

热门文章

  1. 南昌学计算机哪个技校好,2021南昌最好的技校排名前十
  2. HT82V26学习心得
  3. Java按照章节分割大型小说文档
  4. vs2010c语言运行按钮在哪,Visual C++2010如何编写并运行C++程序,vc2010编译按钮在哪里...
  5. 导轨式直流电能表 充电桩直流计量-安科瑞 顾月
  6. 继续分享5个不错javascript游戏
  7. 小米air13.3win10安装Ubuntu18.04双系统
  8. java实现kfc点餐系统
  9. 大型API网关(五)—— 限流
  10. 仿“饿了么”订餐app界面实现