使用 java 对文件进行pgp加密的完整代码
时间: 2023-08-06 08:01:44 浏览: 214
PGP加密软件Java实现
以下是使用 Java 对文件进行 PGP 加密的完整代码:
```java
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.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.KeyFlags;
import org.bouncycastle.crypto.generators.RSAKeyPairGenerator;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.params.KeyGenerationParameters;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPCompressedData;
import org.bouncycastle.openpgp.PGPEncryptedData;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPLiteralData;
import org.bouncycastle.openpgp.PGPObjectFactory;
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 PgpEncryptor {
/**
* 加密文件
*
* @param publicKeyFilePath 公钥文件路径
* @param inputFilePath 待加密文件路径
* @param outputFilePath 加密后文件路径
* @param asciiArmor 是否生成 ASCII Armor 格式的输出文件
* @throws IOException
* @throws PGPException
* @throws NoSuchProviderException
*/
public static void encryptFile(String publicKeyFilePath, String inputFilePath, String outputFilePath, boolean asciiArmor)
throws IOException, PGPException, NoSuchProviderException {
Security.addProvider(new BouncyCastleProvider());
InputStream publicKeyIn = new FileInputStream(publicKeyFilePath);
PGPPublicKeyRingCollection publicKeyRingCollection = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(publicKeyIn));
publicKeyIn.close();
OutputStream out = new FileOutputStream(outputFilePath);
if (asciiArmor) {
out = new ArmoredOutputStream(out);
}
PGPPublicKey publicKey = null;
Iterator<PGPPublicKeyRing> publicKeyRingIterator = publicKeyRingCollection.getKeyRings();
while (publicKey == null && publicKeyRingIterator.hasNext()) {
PGPPublicKeyRing publicKeyRing = publicKeyRingIterator.next();
Iterator<PGPPublicKey> publicKeyIterator = publicKeyRing.getPublicKeys();
while (publicKey == null && publicKeyIterator.hasNext()) {
PGPPublicKey key = publicKeyIterator.next();
if (key.isEncryptionKey()) {
publicKey = key;
}
}
}
if (publicKey == null) {
throw new IllegalArgumentException("Can't find encryption key in key ring.");
}
byte[] buffer = new byte[4096];
int len;
PGPEncryptedDataGenerator encryptedDataGenerator = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256).setWithIntegrityPacket(true).setSecureRandom(new SecureRandom()).setProvider("BC"));
encryptedDataGenerator.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(publicKey).setProvider("BC"));
OutputStream encryptedOut = encryptedDataGenerator.open(out, buffer);
PGPCompressedDataGenerator compressedDataGenerator = new PGPCompressedDataGenerator(CompressionAlgorithmTags.ZIP);
OutputStream compressedOut = compressedDataGenerator.open(encryptedOut);
PGPLiteralDataGenerator literalDataGenerator = new PGPLiteralDataGenerator();
OutputStream literalOut = literalDataGenerator.open(compressedOut, PGPLiteralData.BINARY, inputFilePath, new java.util.Date(), buffer);
InputStream input = new FileInputStream(inputFilePath);
while ((len = input.read(buffer)) > 0) {
literalOut.write(buffer, 0, len);
}
input.close();
literalDataGenerator.close();
compressedDataGenerator.close();
encryptedDataGenerator.close();
out.close();
}
/**
* 读取私钥文件
*
* @param secretKeyFilePath 私钥文件路径
* @return
* @throws IOException
* @throws PGPException
*/
public static PGPSecretKey readSecretKey(String secretKeyFilePath) throws IOException, PGPException {
InputStream secretKeyIn = new FileInputStream(secretKeyFilePath);
PGPSecretKeyRingCollection secretKeyRingCollection = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(secretKeyIn));
secretKeyIn.close();
PGPSecretKey secretKey = null;
Iterator<PGPSecretKeyRing> secretKeyRingIterator = secretKeyRingCollection.getKeyRings();
while (secretKey == null && secretKeyRingIterator.hasNext()) {
PGPSecretKeyRing secretKeyRing = secretKeyRingIterator.next();
Iterator<PGPSecretKey> secretKeyIterator = secretKeyRing.getSecretKeys();
while (secretKey == null && secretKeyIterator.hasNext()) {
PGPSecretKey key = secretKeyIterator.next();
if (key.isSigningKey()) {
secretKey = key;
}
}
}
if (secretKey == null) {
throw new IllegalArgumentException("Can't find signing key in key ring.");
}
return secretKey;
}
/**
* 解密文件
*
* @param secretKeyFilePath 私钥文件路径
* @param passPhrase 私钥密码
* @param encryptedFilePath 待解密文件路径
* @param outputFilePath 解密后文件路径
* @throws IOException
* @throws PGPException
*/
public static void decryptFile(String secretKeyFilePath, char[] passPhrase, String encryptedFilePath, String outputFilePath)
throws IOException, PGPException {
Security.addProvider(new BouncyCastleProvider());
PGPSecretKey secretKey = readSecretKey(secretKeyFilePath);
PGPPrivateKey privateKey = secretKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(passPhrase));
InputStream encryptedIn = new FileInputStream(encryptedFilePath);
PGPObjectFactory pgpFactory = new PGPObjectFactory(PGPUtil.getDecoderStream(encryptedIn));
PGPEncryptedDataList encryptedDataList;
Object object = pgpFactory.nextObject();
if (object instanceof PGPEncryptedDataList) {
encryptedDataList = (PGPEncryptedDataList) object;
} else {
encryptedDataList = (PGPEncryptedDataList) pgpFactory.nextObject();
}
PGPPublicKeyEncryptedData publicKeyEncryptedData = null;
Iterator<PGPEncryptedData> encryptedDataIterator = encryptedDataList.getEncryptedDataObjects();
while (publicKeyEncryptedData == null && encryptedDataIterator.hasNext()) {
PGPEncryptedData encryptedData = encryptedDataIterator.next();
if (encryptedData instanceof PGPPublicKeyEncryptedData) {
publicKeyEncryptedData = (PGPPublicKeyEncryptedData) encryptedData;
}
}
if (publicKeyEncryptedData == null) {
throw new IllegalArgumentException("Can't find public key encrypted data in message.");
}
InputStream decryptedIn = publicKeyEncryptedData.getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider("BC").build(privateKey));
PGPObjectFactory plainFactory = new PGPObjectFactory(decryptedIn);
Object message = plainFactory.nextObject();
if (message instanceof PGPCompressedData) {
PGPCompressedData compressedData = (PGPCompressedData) message;
plainFactory = new PGPObjectFactory(compressedData.getDataStream());
message = plainFactory.nextObject();
}
PGPLiteralData literalData = (PGPLiteralData) message;
InputStream literalIn = literalData.getInputStream();
OutputStream out = new FileOutputStream(outputFilePath);
byte[] buffer = new byte[4096];
int len;
while ((len = literalIn.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
out.close();
}
/**
* 生成密钥对
*
* @param identity 密钥标识
* @param passPhrase 密钥密码
* @param secretKeyFilePath 私钥文件路径
* @param publicKeyFilePath 公钥文件路径
* @throws IOException
* @throws PGPException
*/
public static void generateKeyPair(String identity, char[] passPhrase, String secretKeyFilePath, String publicKeyFilePath)
throws IOException, PGPException {
Security.addProvider(new BouncyCastleProvider());
RSAKeyPairGenerator rsaKeyPairGenerator = new RSAKeyPairGenerator();
rsaKeyPairGenerator.init(new KeyGenerationParameters(new SecureRandom(), 2048));
AsymmetricKeyParameter privateKey = rsaKeyPairGenerator.generateKeyPair().getPrivate();
PGPSecretKey secretKey = new PGPSecretKey(PGPSignature.DEFAULT_CERTIFICATION, PGPPublicKey.RSA_GENERAL, privateKey, new java.util.Date(), identity, SymmetricKeyAlgorithmTags.AES_256, passPhrase, null, null, new SecureRandom(), "BC");
OutputStream secretKeyOut = new FileOutputStream(secretKeyFilePath);
PGPSecretKeyRing secretKeyRing = new PGPSecretKeyRing(secretKey.getEncoded());
secretKeyRing.encode(secretKeyOut);
secretKeyOut.close();
PGPPublicKey publicKey = secretKey.getPublicKey();
OutputStream publicKeyOut = new FileOutputStream(publicKeyFilePath);
PGPPublicKeyRing publicKeyRing = new PGPPublicKeyRing(publicKey.getEncoded());
publicKeyRing.encode(publicKeyOut);
publicKeyOut.close();
}
}
```
使用示例:
```java
public class PgpEncryptorTest {
public static void main(String[] args) {
try {
String publicKeyFilePath = "public.asc";
String privateKeyFilePath = "private.asc";
char[] passPhrase = "123456".toCharArray();
String inputFilePath = "test.txt";
String encryptedFilePath = "test.txt.asc";
String decryptedFilePath = "test.decrypted.txt";
boolean asciiArmor = true;
PgpEncryptor.generateKeyPair("Test User", passPhrase, privateKeyFilePath, publicKeyFilePath);
PgpEncryptor.encryptFile(publicKeyFilePath, inputFilePath, encryptedFilePath, asciiArmor);
PgpEncryptor.decryptFile(privateKeyFilePath, passPhrase, encryptedFilePath, decryptedFilePath);
} catch (Exception e) {
e.printStackTrace();
}
}
}
```
阅读全文