使用 java 对文件进行pgp加密的完整工具类代码
时间: 2024-01-22 08:18:07 浏览: 157
下面是一个使用 BouncyCastle 实现 PGP 加密和解密的 Java 工具类示例:
```java
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
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.security.Security;
import java.util.Date;
import java.util.Iterator;
import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.bcpg.CompressionAlgorithmTags;
import org.bouncycastle.bcpg.HashAlgorithmTags;
import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.bouncycastle.bcpg.sig.Features;
import org.bouncycastle.bcpg.sig.KeyFlags;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPEncryptedData;
import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
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.PGPUtil;
public class PgpEncryptDecryptUtil {
private static final String PROVIDER = "BC";
private static final int BUFFER_SIZE = 4096;
// 加载 BouncyCastle 提供的 JCE 供应商
static {
Security.addProvider(new BouncyCastleProvider());
}
/**
* 加密数据并输出到指定的输出流中
*
* @param data 要加密的数据
* @param publicKeyIn 加载公钥的输入流
* @param outputStream 输出加密后的数据的输出流
* @throws IOException IO异常
* @throws PGPException PGP异常
*/
public static void encrypt(byte[] data, InputStream publicKeyIn, OutputStream outputStream)
throws IOException, PGPException {
// 创建公钥环
PGPPublicKeyRingCollection publicKeyRingCollection = new PGPPublicKeyRingCollection(
PGPUtil.getDecoderStream(publicKeyIn));
// 找到可用的公钥
PGPPublicKey publicKey = null;
Iterator<PGPPublicKeyRing> keyRingIterator = publicKeyRingCollection.getKeyRings();
while (publicKey == null && keyRingIterator.hasNext()) {
PGPPublicKeyRing keyRing = keyRingIterator.next();
Iterator<PGPPublicKey> keyIterator = keyRing.getPublicKeys();
while (publicKey == null && keyIterator.hasNext()) {
PGPPublicKey key = keyIterator.next();
if (key.isEncryptionKey()) {
publicKey = key;
}
}
}
if (publicKey == null) {
throw new IllegalArgumentException("Can't find public key");
}
// 创建加密数据生成器
PGPEncryptedDataGenerator encryptedDataGenerator = new PGPEncryptedDataGenerator(
new JcePGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256)
.setWithIntegrityPacket(true).setSecureRandom(new SecureRandom()).setProvider(PROVIDER));
encryptedDataGenerator.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(publicKey)
.setProvider(PROVIDER));
// 创建压缩输出流
ByteArrayOutputStream compressedOutputStream = new ByteArrayOutputStream();
OutputStream compressedDataOutputStream = new ArmoredOutputStream(compressedOutputStream);
PGPCompressedDataGenerator compressedDataGenerator = new PGPCompressedDataGenerator(
CompressionAlgorithmTags.ZIP);
OutputStream compressedDataOutputStream2 = compressedDataGenerator.open(compressedDataOutputStream);
// 创建字面数据输出流
PGPLiteralDataGenerator literalDataGenerator = new PGPLiteralDataGenerator();
OutputStream literalDataOutputStream = literalDataGenerator.open(compressedDataOutputStream2, PGPLiteralData.BINARY,
PGPLiteralData.CONSOLE, data.length, new Date());
// 写入明文数据
ByteArrayInputStream dataInputStream = new ByteArrayInputStream(data);
byte[] buffer = new byte[BUFFER_SIZE];
int length;
while ((length = dataInputStream.read(buffer, 0, buffer.length)) != -1) {
literalDataOutputStream.write(buffer, 0, length);
}
literalDataOutputStream.close();
// 关闭输出流
compressedDataGenerator.close();
compressedDataOutputStream.close();
compressedOutputStream.close();
// 加密数据并输出到指定输出流
byte[] encryptedData = compressedOutputStream.toByteArray();
OutputStream encryptedDataOutputStream = encryptedDataGenerator.open(outputStream, encryptedData.length);
encryptedDataOutputStream.write(encryptedData);
encryptedDataOutputStream.close();
}
/**
* 解密数据并返回解密后的数据
*
* @param encryptedDataIn 加载加密数据的输入流
* @param privateKeyIn 加载私钥的输入流
* @return 解密后的数据
* @throws IOException IO异常
* @throws PGPException PGP异常
*/
public static byte[] decrypt(InputStream encryptedDataIn, InputStream privateKeyIn)
throws IOException, PGPException {
// 创建私钥环
PGPSecretKeyRingCollection secretKeyRingCollection = new PGPSecretKeyRingCollection(
PGPUtil.getDecoderStream(privateKeyIn));
// 找到可用的私钥
PGPPrivateKey privateKey = null;
Iterator<PGPSecretKeyRing> keyRingIterator = secretKeyRingCollection.getKeyRings();
while (privateKey == null && keyRingIterator.hasNext()) {
PGPSecretKeyRing keyRing = keyRingIterator.next();
Iterator<PGPSecretKey> keyIterator = keyRing.getSecretKeys();
while (privateKey == null && keyIterator.hasNext()) {
PGPSecretKey key = keyIterator.next();
if (key.isSigningKey()) {
privateKey = key.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder()
.setProvider(PROVIDER).build("".toCharArray()));
}
}
}
if (privateKey == null) {
throw new IllegalArgumentException("Can't find private key");
}
// 创建对象工厂
PGPObjectFactory objectFactory = new PGPObjectFactory(PGPUtil.getDecoderStream(encryptedDataIn));
Object object = objectFactory.nextObject();
// 找到加密数据包
PGPEncryptedData encryptedData = null;
while (encryptedData == null && object != null) {
if (object instanceof PGPEncryptedData) {
encryptedData = (PGPEncryptedData) object;
} else {
object = objectFactory.nextObject();
}
}
if (encryptedData == null) {
throw new IllegalArgumentException("Can't find encrypted data");
}
// 找到公钥并解密数据
InputStream encryptedDataInputStream = encryptedData.getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder()
.setProvider(PROVIDER).build(privateKey));
PGPObjectFactory encryptedObjectFactory = new PGPObjectFactory(encryptedDataInputStream);
object = encryptedObjectFactory.nextObject();
// 找到签名列表并校验签名
PGPOnePassSignatureList signatureList = null;
while (signatureList == null && object != null) {
if (object instanceof PGPOnePassSignatureList) {
signatureList = (PGPOnePassSignatureList) object;
} else {
object = encryptedObjectFactory.nextObject();
}
}
if (signatureList != null) {
throw new PGPException("This implementation doesn't support signed data");
}
// 找到字面数据包并解压缩数据
PGPLiteralData literalData = null;
while (literalData == null && object != null) {
if (object instanceof PGPLiteralData) {
literalData = (PGPLiteralData) object;
} else {
object = encryptedObjectFactory.nextObject();
}
}
if (literalData == null) {
throw new IllegalArgumentException("Can't find literal data");
}
ByteArrayOutputStream uncompressedOutputStream = new ByteArrayOutputStream();
InputStream compressedDataInputStream = literalData.getInputStream();
PGPCompressedData compressedData = new PGPCompressedData(compressedDataInputStream);
InputStream uncompressedDataInputStream = compressedData.getDataStream();
byte[] buffer = new byte[BUFFER_SIZE];
int length;
while ((length = uncompressedDataInputStream.read(buffer, 0, buffer.length)) != -1) {
uncompressedOutputStream.write(buffer, 0, length);
}
uncompressedDataInputStream.close();
compressedDataInputStream.close();
uncompressedOutputStream.close();
return uncompressedOutputStream.toByteArray();
}
/**
* 加载公钥环
*
* @param publicKeyRingIn 加载公钥环的输入流
* @return 公钥环
* @throws IOException IO异常
* @throws PGPException PGP异常
*/
public static PGPPublicKeyRingCollection loadPublicKeyRing(InputStream publicKeyRingIn)
throws IOException, PGPException {
return new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(publicKeyRingIn));
}
/**
* 加载私钥环
*
* @param secretKeyRingIn 加载私钥环的输入流
* @return 私钥环
* @throws IOException IO异常
* @throws PGPException PGP异常
*/
public static PGPSecretKeyRingCollection loadSecretKeyRing(InputStream secretKeyRingIn)
throws IOException, PGPException {
return new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(secretKeyRingIn));
}
/**
* 从文件中加载公钥环
*
* @param publicKeyRingFile 加载公钥环的文件
* @return 公钥环
* @throws IOException IO异常
* @throws PGPException PGP异常
*/
public static PGPPublicKeyRingCollection loadPublicKeyRingFromFile(String publicKeyRingFile)
throws IOException, PGPException {
FileInputStream fileInputStream = new FileInputStream(publicKeyRingFile);
PGPPublicKeyRingCollection publicKeyRingCollection = loadPublicKeyRing(fileInputStream);
fileInputStream.close();
return publicKeyRingCollection;
}
/**
* 从文件中加载私钥环
*
* @param secretKeyRingFile 加载私钥环的文件
* @return 私钥环
* @throws IOException IO异常
* @throws PGPException PGP异常
*/
public static PGPSecretKeyRingCollection loadSecretKeyRingFromFile(String secretKeyRingFile)
throws IOException, PGPException {
FileInputStream fileInputStream = new FileInputStream(secretKeyRingFile);
PGPSecretKeyRingCollection secretKeyRingCollection = loadSecretKeyRing(fileInputStream);
fileInputStream.close();
return secretKeyRingCollection;
}
/**
* 保存公钥环到文件中
*
* @param publicKeyRing 要保存的公钥环
* @param publicKeyRingFileOut 保存公钥环的文件输出流
* @throws IOException IO异常
*/
public static void savePublicKeyRing(PGPPublicKeyRing publicKeyRing, OutputStream publicKeyRingFileOut)
throws IOException {
ArmoredOutputStream armoredOutputStream = new ArmoredOutputStream(publicKeyRingFileOut);
publicKeyRing.encode(armoredOutputStream);
armoredOutputStream.close();
}
/**
* 保存私钥环到文件中
*
* @param secretKeyRing 要保存的私钥环
* @param secretKeyRingFileOut 保存私钥环的文件输出流
* @throws IOException IO异常
*/
public static void saveSecretKeyRing(PGPSecretKeyRing secretKeyRing, OutputStream secretKeyRingFileOut)
throws IOException {
ArmoredOutputStream armoredOutputStream = new ArmoredOutputStream(secretKeyRingFileOut);
secretKeyRing.encode(armoredOutputStream);
armoredOutputStream.close();
}
/**
* 保存公钥环到文件中
*
* @param publicKeyRing 要保存的公钥环
* @param publicKeyRingFileOut 保存公钥环的文件输出流
* @throws IOException IO异常
*/
public static void savePublicKeyRingToFile(PGPPublicKeyRing publicKeyRing, String publicKeyRingFileOut)
throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream(publicKeyRingFileOut);
savePublicKeyRing(publicKeyRing, fileOutputStream);
fileOutputStream.close();
}
/**
* 保存私钥环到文件中
*
* @param secretKeyRing 要保存的私钥环
* @param secretKeyRingFileOut 保存私钥环的文件输出流
* @throws IOException IO异常
*/
public static void saveSecretKeyRingToFile(PGPSecretKeyRing secretKeyRing, String secretKeyRingFileOut)
throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream(secretKeyRingFileOut);
saveSecretKeyRing(secretKeyRing, fileOutputStream);
fileOutputStream.close();
}
/**
* 创建公钥环
*
* @param keyPair 密钥对
* @param userId 用户ID
* @param keyRingName 密钥环名称
* @param expirationTimeInDays 过期时间(以天为单位)
* @return 公钥环
* @throws PGPException PGP异常
*/
public static PGPPublicKeyRing createPublicKeyRing(PgpKeyPair keyPair, String userId, String keyRingName,
int expirationTimeInDays) throws PGPException {
PGPPublicKeyRingGenerator publicKeyRingGenerator = new PGPPublicKeyRingGenerator(
PGPSignature.POSITIVE_CERTIFICATION, keyPair.getPublicKey(), userId,
new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256, new SecureRandom())
.setProvider(PROVIDER).build(keyPair.getPassphrase().toCharArray()),
null, null, new JcaPGPContentSignerBuilder(keyPair.getPublicKey().getAlgorithm(),
HashAlgorithmTags.SHA256), new JcePGPKeyEncryptionMethodGenerator(keyPair.getPublicKey().getAlgorithm())
.setProvider(PROVIDER), new SecureRandom(), new Date());
if (expirationTimeInDays > 0) {
publicKeyRingGenerator.addSubKey(keyPair.getPublicKey(),
new Date(System.currentTimeMillis() + expirationTimeInDays * 86400000L),
new JcaPGPContentSignerBuilder(keyPair.getPublicKey().getAlgorithm(),
HashAlgorithmTags.SHA256),
new JcePGPKeyEncryptionMethodGenerator(keyPair.getPublicKey().getAlgorithm()).setProvider(PROVIDER));
}
return publicKeyRingGenerator.generatePublicKeyRing();
}
/**
* 创建私钥环
*
* @param keyPair 密钥对
* @param userId 用户ID
* @param keyRingName 密钥环名称
* @param expirationTimeInDays 过期时间(以天为单位)
* @return 私钥环
* @throws PGPException PGP异常
*/
public static PGPSecretKeyRing createSecretKeyRing(PgpKeyPair keyPair, String userId, String keyRingName,
int expirationTimeInDays) throws PGPException {
PGPPublicKey publicKey = keyPair.getPublicKey();
PGPSecretKey secretKey = new PGPSecretKey(PGPSignature.DEFAULT_CERTIFICATION, publicKey,
new JcaPGPContentSignerBuilder(publicKey.getAlgorithm(), HashAlgorithmTags.SHA256),
new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256, new SecureRandom())
.setProvider(PROVIDER).build(keyPair.getPassphrase().toCharArray()), null, null,
new JcaPGPContentSignerBuilder(publicKey.getAlgorithm(), HashAlgorithmTags.SHA256),
new JcePGPKeyEncryptionMethodGenerator(publicKey.getAlgorithm()).setProvider(PROVIDER));
if (expirationTimeInDays > 0) {
secretKey = PGPSecretKey.addSecretSubKey(secretKey, keyPair.getPrivateKey(),
new Date(System.currentTimeMillis() + expirationTimeInDays * 86400000L),
new JcaPGPContentSignerBuilder(publicKey.getAlgorithm(), HashAlgorithmTags.SHA256),
new JcePGPKeyEncryptionMethodGenerator(publicKey.getAlgorithm()).setProvider(PROVIDER));
}
return new PGPSecretKeyRing(secretKey.getEncoded());
}
/**
* 创建密钥对
*
* @param keySize 密钥长度
* @param passphrase 密码
* @return 密钥对
* @throws PGPException PGP异常
*/
public static PgpKeyPair createKeyPair(int keySize, String passphrase) throws PGPException {
JcaPGPKeyPairGenerator keyPairGenerator = new JcaPGPKeyPairGenerator().setProvider(PROVIDER);
keyPairGenerator.generate(keySize, new SecureRandom());
PGPKeyPair keyPair = keyPairGenerator.generateKeyPair();
return new PgpKeyPair(keyPair.getPublicKey(), keyPair.getPrivateKey(), passphrase);
}
/**
* 加载密钥对
*
* @param publicKeyIn 加载公钥的输入流
* @param privateKeyIn 加载私钥的输入流
* @param passphrase 密码
* @return 密钥对
* @throws IOException IO异常
* @throws PGPException PGP异常
*/
public static PgpKeyPair loadKeyPair(InputStream publicKeyIn, InputStream privateKeyIn, String passphrase)
throws IOException,
阅读全文