首先请大家一定要搞清楚加密解密概念:
下面这是百度出来的。
如果只是单方面采用非对称性加密算法,其实有两种方式,用于不同用处.
-
第一种是签名,使用私钥加密,公钥解密,用于让所有公钥所有者验证私钥所有者的身份并且用来防止私钥所有者发布的内容被篡改.但是不用来保证内容不被他人获得.
-
第二种是加密,用公钥加密,私钥解密,用于向公钥所有者发布信息,这个信息可能被他人篡改,但是无法被他人获得.
如果甲想给乙发一个安全的保密的数据,那么应该甲乙各自有一个私钥,甲先用乙的公钥加密这段数据,再用自己的私钥加密这段加密后的数据.最后再发给乙,这样确保了内容即不会被读取,也不会被篡改.
折磨了我一个星期,就是因为配合的同事跟我说用公钥解密,所以一定要搞清楚概念。
代码块:
KeyBasedLargeFileProcessor.java
import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.*;
import org.bouncycastle.openpgp.bc.BcPGPObjectFactory;
import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory;
import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;
import org.bouncycastle.util.io.Streams;
import java.io.*;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Iterator;
/*
* 加密与解密
* */
public class KeyBasedLargeFileProcessor {
/*
* 解密
* @Para inputFileName 输入的文件路径
* @Para keyFileName 私钥文件路径
* @Para passwd 私钥密码
* @Para defaultFileName 输出文件路径
* */
public static void decryptFile(
String inputFileName,
String keyFileName,
char[] passwd,
String defaultFileName)
throws IOException, NoSuchProviderException {
InputStream in = new BufferedInputStream(new FileInputStream(inputFileName));
InputStream keyIn = new BufferedInputStream(new FileInputStream(keyFileName));
decryptFile(in, keyIn, passwd, defaultFileName);
keyIn.close();
in.close();
}
public static void decryptFile(
InputStream in,
InputStream keyIn,
char[] passwd,
String defaultFileName)
throws IOException, NoSuchProviderException {
in = PGPUtil.getDecoderStream(in);
try {
//创建PGP对象
JcaPGPObjectFactory pgpF = new JcaPGPObjectFactory(in);
//PGP加密的数据列表
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 it = enc.getEncryptedDataObjects();
PGPPrivateKey sKey = null;
//公钥加密数据
PGPPublicKeyEncryptedData pbe = null;
PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(
PGPUtil.getDecoderStream(keyIn),new JcaKeyFingerprintCalculator());
System.out.println("pgpSec=" + pgpSec);
while (sKey == null && it.hasNext()) {
pbe = (PGPPublicKeyEncryptedData) it.next();
System.out.println("pbe=" + pbe);
sKey = PGPExampleUtil.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)));
//解密数据的对象流
PGPObjectFactory plainFact = new JcaPGPObjectFactory(clear);
//压缩解密对象
PGPCompressedData cData = (PGPCompressedData) plainFact.nextObject();
//获得压缩对象流
InputStream compressedStream = new BufferedInputStream(cData.getDataStream());
PGPObjectFactory pgpFact = new BcPGPObjectFactory(compressedStream);
Object message = pgpFact.nextObject();
if (message instanceof PGPLiteralData) {
PGPLiteralData ld = (PGPLiteralData) message;
String outFileName = ld.getFileName();
if (outFileName.length() != 0) {
outFileName = defaultFileName;
}
InputStream unc = ld.getInputStream();
OutputStream fOut = new BufferedOutputStream(new FileOutputStream(outFileName));
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()) {
System.err.println("message failed integrity check");
} else {
System.err.println("message integrity check passed");
}
} else {
System.err.println("no message integrity check");
}
} catch (PGPException e) {
System.err.println(e);
if (e.getUnderlyingException() != null) {
e.getUnderlyingException().printStackTrace();
}
}
}
/*
* 加密
* @Para outputFileName 输出文件的路径
* @Para inputFileName 输入文件的路径
* @Para encKeyFileName 公钥
* @Para armor
* @Para withIntegrityCheck 完整性检查
* */
public static void encryptFile(
String outputFileName,
String inputFileName,
String encKeyFileName,
boolean armor,
boolean withIntegrityCheck)
throws IOException, NoSuchProviderException, PGPException {
OutputStream out = new BufferedOutputStream(new FileOutputStream(outputFileName));
PGPPublicKey encKey = PGPExampleUtil.readPublicKey(encKeyFileName);
encryptFile(out, inputFileName, encKey, armor, withIntegrityCheck);
out.close();
}
public static void encryptFile(
OutputStream out,
String fileName,
PGPPublicKey encKey,
boolean armor,
boolean withIntegrityCheck)
throws IOException, NoSuchProviderException {
if (armor) {
out = new ArmoredOutputStream(out);
}
try {
PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(withIntegrityCheck).setSecureRandom(new SecureRandom()).setProvider("BC"));
cPk.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(encKey).setProvider("BC"));
OutputStream cOut = cPk.open(out, new byte[1 << 16]);
PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(
PGPCompressedData.ZIP);
PGPUtil.writeFileToLiteralData(comData.open(cOut), PGPLiteralData.BINARY, new File(fileName), new byte[1 << 16]);
comData.close();
cOut.close();
if (armor) {
out.close();
}
} catch (PGPException e) {
System.err.println(e);
if (e.getUnderlyingException() != null) {
e.getUnderlyingException().printStackTrace();
}
}
}
public static void main(
String[] args)
throws Exception {
Security.addProvider(new BouncyCastleProvider());
//encryptFile("D://1.PGP.tmp","D://123.txt","D://kkprivate.asc",true,true);
decryptFile("D://104110082202643_ODD_02_20191227.PGP", "D://kkprivate.asc", "67216688".toCharArray(), "D://104110082202643_ODD_02_20191227.txt");
}
}
PGPExampleUtil.java
package org.kxsj.com.pgp;
import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.bcpg.BCPGOutputStream;
import org.bouncycastle.bcpg.HashAlgorithmTags;
import org.