提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
PGP加解密
一、PGP是什么?
PGP全称 Pretty Good Privacy, 由Phil Zimmermann在1991年开发,开源后由各个组织开发过不同版本的PGP实现,后由IETF成立OPenPGP工作组并统一制定了一套标准,也是本文中使用的版本。
-
PGP:由Phil Zimmermann开发,最终被赛门铁克收购,被收购后是一个商业软件,需要付费。
-
OpenPGP:由开源组织规范的PGP协议,定义了加密消息、签名、私钥和用于交换公钥的证书统一标准。
-
GPG(GnuPG):符合OpenPGP标准的开源加密软件,PGP的开源实现。
二、使用步骤
1.引入库
使用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>
<!--工具集,非必须-->
<dependency>
<groupId>name.neuhalfen.projects.crypto.bouncycastle.openpgp</groupId>
<artifactId>bouncy-gpg</artifactId>
<version>2.2.0</version>
</dependency>
<!--断言工具,非必须-->
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.16.1</version>
</dependency>
2.生成秘钥对
private static BouncyCastleProvider provider;
private static SecureRandom secureRandom;
static {
provider = new BouncyCastleProvider();
secureRandom = new SecureRandom();
Security.addProvider(provider);
}
/**
* <pre>
* to generate PGP key pairs.
* usage: generatePGPKeyPair(2048, true, "tom", "my pass", "/www/pub", "/www/pri");
* return key pairs, str[0]=publicKey, str[1]=privateKey.
* if armor, return armored key string, if unarmored, return key path.
* </pre>
*
* @param keyWidth key width, 1024/2048/3072/4096, recommend 2048
* @param armor designate if key format with armored or not
* @param identity key holder's identity, recommend write as email
* @param passPhrase password to open private key
* @return return key pairs, str[0]=publicKey, str[1]=privateKey.
* @throws Exception
*/
public static String[] generatePGPKeyPair(int keyWidth, boolean armor, String identity, String passPhrase,
String pubKeyFile, String priKeyFile) throws Exception {
KeyPairGenerator var1 = KeyPairGenerator.getInstance(MyPGPUtil.RSA, MyPGPUtil.PROVIDER_BC);
var1.initialize(keyWidth);
KeyPair var2 = var1.generateKeyPair();
OutputStream var3;
OutputStream var4;
try (ByteArrayOutputStream pubKeyOut = new ByteArrayOutputStream();
ByteArrayOutputStream priKeyOut = new ByteArrayOutputStream();
) {
if (armor) {
// key format with armored
var3 = new ArmoredOutputStream(priKeyOut);
var4 = new ArmoredOutputStream(pubKeyOut);
} else {
// key format without armored
var3 = new FileOutputStream(priKeyFile);
var4 = new FileOutputStream(pubKeyFile);
}
// the pass phrase for open private key
char[] var11 = passPhrase.toCharArray();
PGPDigestCalculator var6 = (new JcaPGPDigestCalculatorProviderBuilder()).build().get(2);
JcaPGPKeyPair var7 = new JcaPGPKeyPair(1, var2, new Date());
PGPSecretKey var8 = new PGPSecretKey(16, var7, identity, var6, (PGPSignatureSubpacketVector) null,
(PGPSignatureSubpacketVector) null, new JcaPGPContentSignerBuilder(var7.getPublicKey().getAlgorithm(), 8),
(new JcePBESecretKeyEncryptorBuilder(3, var6)).setProvider(MyPGPUtil.PROVIDER_BC).build(var11));
var8.encode(var3);
(var3).close();
PGPPublicKey var9 = var8.getPublicKey();
var9.encode(var4);
(var4).close();
// build return result
String[] keyPair = new String[2];
if (armor) {
keyPair[0] = pubKeyOut.toString();
keyPair[1] = priKeyOut.toString();
} else {
keyPair[0] = pubKeyFile;
keyPair[1] = priKeyFile;
}
return keyPair;
}
}
3. 加密并签名
使用接收者的公钥加密,使用发送者的私钥签名
import java.io.*;
import java.security.*;
import java.util.Date;
import java.util.Iterator;
import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.bcpg.HashAlgorithmTags;
import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
import o