基于Java代码进行GPG加解密
依赖
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcpg-jdk15on -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpg-jdk15on</artifactId>
<version>1.65</version>
</dependency>
初始化
Security.addProvider(new BouncyCastleProvider());
辅助类
@Slf4j
public class PGPFileProcessor {
public static void decryptFile(String inputFilePath, String keyFilePath, char[] passWd, String outputFilePath)
throws IOException, NoSuchProviderException {
InputStream in = new BufferedInputStream(new FileInputStream(inputFilePath));
InputStream keyIn = new BufferedInputStream(new FileInputStream(keyFilePath));
decryptFile(in, keyIn, passWd, outputFilePath);
keyIn.close();
in.close();
}
public static void decryptFile(File inputFile, String keyFilePath, char[] passWd, File outputFile)
throws IOException, NoSuchProviderException {
InputStream in = new BufferedInputStream(new FileInputStream(inputFile));
InputStream keyIn = new BufferedInputStream(new FileInputStream(keyFilePath));
decryptFile(in, keyIn, passWd, outputFile.getAbsolutePath());
keyIn.close();
in.close();
}
/**
* decrypt the passed in message stream
*/
private static void decryptFile(InputStream in, InputStream keyIn, char[] passWd, String outputFilePath)
throws IOException, NoSuchProviderException {
in = PGPUtil.getDecoderStream(in);
try {
JcaPGPObjectFactory pgpF = new JcaPGPObjectFactory(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<PGPEncryptedData> it = enc.getEncryptedDataObjects();
PGPPrivateKey sKey = null;
PGPPublicKeyEncryptedData pbe = null;
PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(
PGPUtil.getDecoderStream(keyIn), new JcaKeyFingerprintCalculator());
while (sKey == null && it.hasNext()) {
pbe = (PGPPublicKeyEncryptedData) it.next();
sKey = PGPHelper.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));
JcaPGPObjectFactory plainFact = new JcaPGPObjectFactory(clear);
Object message = plainFact.nextObject();
if (message instanceof PGPCompressedData) {
PGPCompressedData cData = (PGPCompressedData) message;
JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(cData.getDataStream());
message = pgpFact.nextObject();
}
if (message instanceof PGPLiteralData) {
PGPLiteralData ld = (PGPLiteralData) message;
String outFilePath = ld.getFileName();
if (outFilePath.length() == 0) {
outFilePath = outputFilePath;
} else {
outFilePath = outputFilePath;
}
InputStream unc = ld.getInputStream();
OutputStream fOut = new BufferedOutputStream(new FileOutputStream(outFilePath));
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()) {
log.error("PGP.decryptFile: message failed integrity check");
} else {
log.info("PGP.decryptFile: message integrity check passed");
}
} else {
log.error("PGP.decryptFile: no message integrity check");
}
} catch (PGPException e) {
log.error("PGP.decryptFile exception: ", e);
if (e.getUnderlyingException() != null) {
log.error("PGP.decryptFile underlying exception: ", e.getUnderlyingException());
}
}
}
public static void encryptFile(String outputFilePath, String inputFilePath, String encKeyFilePath,
boolean armor, boolean withIntegrityCheck)
throws IOException, NoSuchProviderException, PGPException {
OutputStream out = new BufferedOutputStream(new FileOutputStream(outputFilePath));
PGPPublicKey encKey = PGPHelper.readPublicKey(encKeyFilePath);
encryptFile(out, inputFilePath, encKey, armor, withIntegrityCheck);
out.close();
}
private static void encryptFile(OutputStream out, String inputFilePath, PGPPublicKey encKey,
boolean armor, boolean withIntegrityCheck)
throws IOException, NoSuchProviderException {
if (armor) {
out = new ArmoredOutputStream(out);
}
try {
byte[] bytes = PGPHelper.compressFile(inputFilePath, CompressionAlgorithmTags.ZIP);
PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(
new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(withIntegrityCheck).setSecureRandom(new SecureRandom()).setProvider("BC"));
encGen.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(encKey).setProvider("BC"));
OutputStream cOut = encGen.open(out, bytes.length);
cOut.write(bytes);
cOut.close();
if (armor) {
out.close();
}
} catch (PGPException e) {
log.error("PGP.encryptFile exception: ", e);
if (e.getUnderlyingException() != null) {
log.error("PGP.encryptFile underlying exception: ", e.getUnderlyingException());
}
}
}
//主方法
public static void main(String[] s) throws Exception {
Security.addProvider(new BouncyCastleProvider());
String inputPath = "E:\\AppBlog\\test.csv.gpg";
String outputPath = "E:\\AppBlog\\test.csv";
String password = "appblog.cn"; //私钥的Key
String privateKey = "E:\\AppBlog\\test.key"; //私钥地址
decryptFile(inputPath, privateKey, password.toCharArray(), outputPath);
}
}
public class PGPHelper {
public 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 the private key.
* @throws PGPException
* @throws NoSuchProviderException
*/
public static PGPPrivateKey findSecretKey(PGPSecretKeyRingCollection pgpSec, long keyID, char[] pass)
throws PGPException, NoSuchProviderException {
PGPSecretKey pgpSecKey = pgpSec.getSecretKey(keyID);
if (pgpSecKey == null) {
return null;
}
return pgpSecKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(pass));
}
public static PGPPublicKey readPublicKey(String fileName) throws IOException, PGPException {
InputStream keyIn = new BufferedInputStream(new FileInputStream(fileName));
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 data stream containing the public key data
* @return the first public key found.
* @throws IOException
* @throws PGPException
*/
public static PGPPublicKey readPublicKey(InputStream input) throws IOException, PGPException {
PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(
PGPUtil.getDecoderStream(input), new JcaKeyFingerprintCalculator());
// 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<PGPPublicKeyRing> keyRingIter = pgpPub.getKeyRings();
while (keyRingIter.hasNext()) {
PGPPublicKeyRing keyRing = keyRingIter.next();
Iterator<PGPPublicKey> keyIter = keyRing.getPublicKeys();
while (keyIter.hasNext()) {
PGPPublicKey key = keyIter.next();
if (key.isEncryptionKey()) {
return key;
}
}
}
throw new IllegalArgumentException("Can't find encryption key in key ring.");
}
public 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.
*/
public static PGPSecretKey readSecretKey(InputStream input) throws IOException, PGPException {
PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(
PGPUtil.getDecoderStream(input), new JcaKeyFingerprintCalculator());
// 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<PGPSecretKeyRing> keyRingIter = pgpSec.getKeyRings();
while (keyRingIter.hasNext()) {
PGPSecretKeyRing keyRing = keyRingIter.next();
Iterator<PGPSecretKey> keyIter = keyRing.getSecretKeys();
while (keyIter.hasNext()) {
PGPSecretKey key = keyIter.next();
if (key.isSigningKey()) {
return key;
}
}
}
throw new IllegalArgumentException("Can't find signing key in key ring.");
}
}
版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/03/25/gpg-encryption-and-decryption-based-on-java/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。
THE END
0
二维码
打赏
海报
基于Java代码进行GPG加解密
依赖
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcpg-jdk15on -->
<dependency>
<groupId>org.bouncycastle</grou……
文章目录
关闭
共有 0 条评论