1,首先了解什么是PGP,PGP的工作原理是什么?这个直接百度百科,我不啰嗦。
PGP是英文 PrettyGood Privacy(更好地保护隐私)的简称,
百度百科介绍:
http://baike.baidu.com/link?url=5cONqc560BbLi0pFPQZ_shK1IrK_LzkjL8LpS9SW_AtXfDF-OXmBaclSeYv6WSMvnWv9cHWsmsUu5emyg8w39K
2,PGP加解密工具的使用。
我这里介绍一款免费的轻量级的PGP工具 Portable PGP,地址如下:
https://sourceforge.net/projects/ppgp/
安装:
下一步
选择安装路径
首次进入 : 填写 name e-mail conment
点击 Encrypt, 命名加密后的文件名,保存
以上过程是加密过程
以上是解密过程
5,以上是使用工具进行PGP的加密,解密的步骤;接下来我们测试一下基于java的加解密步骤。(这里只演示解密过程)
下载Bouncy Castle:Bouncy Castle支持大量的密码术算法,其中包括OpenPGP,引用很广泛,Pega就是使用Bouncy Castle对邮件和客户重要数据进行加密解密的。
地址: http://www.bouncycastle.org/latest_releases.html
bcprov-jdk15on-155.jar,bcpg-jdk15on-155.jar (大家看到的时候,版本可能已经更新了)
6,Oracle官网下载UnlimitedJCEPolicy:JDK默认Policy只能支持<=128位Key,GPG的密钥从1024-2048,所以必须扩展该Policy。
地址: http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
将下载的local_policy.jar ,US_export_policy.jar两个JAR覆盖系统jre环境下的两个JAR;如:../jre/lib/security/ ,建议先把原来的备份吧,以后有问题可以
KeyBasedFileProcessor.java 和 PGPExampleUti.java 是源码(别人说的,我找没找到,尴尬。。)
package com.pgp.iquant;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
importjava.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Iterator;
importorg.bouncycastle.bcpg.ArmoredOutputStream;
importorg.bouncycastle.bcpg.CompressionAlgorithmTags;
importorg.bouncycastle.jce.provider.BouncyCastleProvider;
importorg.bouncycastle.openpgp.PGPCompressedData;
importorg.bouncycastle.openpgp.PGPEncryptedData;
importorg.bouncycastle.openpgp.PGPEncryptedDataGenerator;
importorg.bouncycastle.openpgp.PGPEncryptedDataList;
import org.bouncycastle.openpgp.PGPException;
importorg.bouncycastle.openpgp.PGPLiteralData;
importorg.bouncycastle.openpgp.PGPOnePassSignatureList;
importorg.bouncycastle.openpgp.PGPPrivateKey;
importorg.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData;
importorg.bouncycastle.openpgp.PGPSecretKeyRingCollection;
import org.bouncycastle.openpgp.PGPUtil;
importorg.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory;
importorg.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
importorg.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
importorg.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder;
importorg.bouncycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;
import org.bouncycastle.util.io.Streams;
/**
*
* Asimple utility class that encrypts/decrypts public key based
*
*encryption files.
*
*<p>
*
* Toencrypt a file: KeyBasedFileProcessor –e [–a|–ai] fileName publicKeyFile.
*<br>
*
* If–a is specified the output file will be "ascii–armored".
*
* If–i is specified the output file will be have integrity checking added.
*
*<p>
*
* Todecrypt: KeyBasedFileProcessor –d fileName secretKeyFile passPhrase.
*
*<p>
*
*Note 1: this example will silently overwrite files, nor does it pay any
*attention to
*
*the specification of "_CONSOLE" in the filename. It also expects thata
*single pass phrase
*
*will have been used.
*
*<p>
*
*Note 2: if an empty file name has been specified in the literal data object
*contained in the
*
*encrypted packet a file with the name filename.out will be generated in the
*current working directory.
*
*/
public class KeyBasedFileProcessor
{
privatestatic void decryptFile(
StringinputFileName,
StringkeyFileName,
char[]passwd,
StringdefaultFileName)
throwsIOException, NoSuchProviderException
{
InputStreamin = new BufferedInputStream(new FileInputStream(inputFileName));
InputStreamkeyIn = new BufferedInputStream(new FileInputStream(keyFileName));
decryptFile(in,keyIn, passwd, defaultFileName);
keyIn.close();
in.close();
}
/**
*
* decrypt the passed in message stream
*
*/
privatestatic void decryptFile(
InputStreamin,
InputStreamkeyIn,
char[]passwd,
StringdefaultFileName)
throwsIOException, NoSuchProviderException
{
in= PGPUtil.getDecoderStream(in);
try
{
JcaPGPObjectFactorypgpF = new JcaPGPObjectFactory(in);
PGPEncryptedDataListenc;
Objecto = 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
//
Iteratorit = enc.getEncryptedDataObjects();
PGPPrivateKeysKey = null;
PGPPublicKeyEncryptedDatapbe = null;
PGPSecretKeyRingCollectionpgpSec = new PGPSecretKeyRingCollection(
PGPUtil.getDecoderStream(keyIn),new JcaKeyFingerprintCalculator());
while(sKey == null && it.hasNext())
{
pbe= (PGPPublicKeyEncryptedData) it.next();
sKey= PGPExampleUtil.findSecretKey(pgpSec, pbe.getKeyID(), passwd);
}
if(sKey == null)
{
thrownew IllegalArgumentException("secret key for message not found.");
}
InputStreamclear = pbe
.getDataStream(newJcePublicKeyDataDecryptorFactoryBuilder().setProvider("BC").build(sKey));
JcaPGPObjectFactoryplainFact = new JcaPGPObjectFactory(clear);
Objectmessage = plainFact.nextObject();
if(message instanceof PGPCompressedData)
{
PGPCompressedDatacData = (PGPCompressedData) message;
JcaPGPObjectFactorypgpFact = new JcaPGPObjectFactory(cData.getDataStream());
message= pgpFact.nextObject();
}
if(message instanceof PGPLiteralData)
{
PGPLiteralDatald = (PGPLiteralData) message;
StringoutFileName = ld.getFileName();
System.out.println("--------------"+outFileName);
if(outFileName.length() == 0)
{
outFileName= defaultFileName;
}else {
/**
*
* modify 20160520
*
* set fileName
*
* 不同的系统可能源文件的包含的路径信息不同。
*
*/
Stringseparator = "";
if(outFileName.contains("/")) {
separator= "/";
}else if (outFileName.contains("\\")) {
separator = "\\";
}
StringfileName;
if(separator.equals("")){
fileName= outFileName;
}else{
fileName =outFileName.substring(outFileName.lastIndexOf(separator));
}
//
Stringdefseparator = "";
if(defaultFileName.contains("/")) {
defseparator= "/";
}else if (defaultFileName.contains("\\")) {
defseparator= "\\";
}
defaultFileName= defaultFileName.substring(0, defaultFileName.lastIndexOf(defseparator));
outFileName =defaultFileName + File.separator + fileName;
}
InputStreamunc = ld.getInputStream();
OutputStreamfOut = new BufferedOutputStream(new FileOutputStream(outFileName));
Streams.pipeAll(unc,fOut);
fOut.close();
}
elseif (message instanceof PGPOnePassSignatureList)
{
thrownew PGPException("encrypted message contains a signed message – notliteral data.");
}
else
{
thrownew PGPException("message is not a simple encrypted file – type unknown.");
}
if(pbe.isIntegrityProtected())
{
if(!pbe.verify())
{
System.err.println("messagefailed integrity check");
}
else
{
System.err.println("messageintegrity check passed");
}
}
else
{
System.err.println("nomessage integrity check");
}
}
catch(PGPException e)
{
System.err.println(e);
if(e.getUnderlyingException() != null)
{
e.getUnderlyingException().printStackTrace();
}
}
}
privatestatic void encryptFile(
StringoutputFileName,
StringinputFileName,
StringencKeyFileName,
booleanarmor,
booleanwithIntegrityCheck)
throwsIOException, NoSuchProviderException, PGPException
{
OutputStreamout = new BufferedOutputStream(new FileOutputStream(outputFileName));//加密文件
PGPPublicKeyencKey = PGPExampleUtil.readPublicKey(encKeyFileName);//密钥文件
encryptFile(out,inputFileName, encKey, armor, withIntegrityCheck);
out.close();
System.out.println("加密完成");
}
privatestatic void encryptFile(
OutputStreamout,
StringfileName,
PGPPublicKeyencKey,
booleanarmor,
booleanwithIntegrityCheck)
throwsIOException, NoSuchProviderException
{
if(armor)
{
out= new ArmoredOutputStream(out);
}
try
{
byte[]bytes = PGPExampleUtil.compressFile(fileName, CompressionAlgorithmTags.ZIP);
PGPEncryptedDataGeneratorencGen = new PGPEncryptedDataGenerator(
newJcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(withIntegrityCheck)
.setSecureRandom(newSecureRandom()).setProvider("BC"));
encGen.addMethod(newJcePublicKeyKeyEncryptionMethodGenerator(encKey).setProvider("BC"));
OutputStreamcOut = encGen.open(out, bytes.length);
cOut.write(bytes);
cOut.close();
if(armor)
{
out.close();
}
}
catch(PGPException e)
{
System.err.println(e);
if(e.getUnderlyingException() != null)
{
e.getUnderlyingException().printStackTrace();
}
}
}
publicstatic void main(String[] args)throws Exception{
Security.addProvider(newBouncyCastleProvider());
//解密 加密文件 私钥 密码
// decryptFile("C:/Users/hucong/Desktop/assets.gpg.zip",
// "F:/workspace/PGP/src/com/privateKey.asc", "123456".toCharArray(),
// "C:/Users/hucong/Desktop/assets001.zip");
//加密 加密后的文件 加密文件 公钥 是否防护 完整性验证
encryptFile("F:/workspace/PGP/src/com/pgp/iquant/PGP01_test.pgp","F:/workspace/PGP/src/com/pgp/iquant/PGP_test.txt","F:/workspace/PGP/src/com/pgp/iquant/publicKey.asc", false, true);
/*
* if (args.length == 0)
*
* {d
*
* System.err.println(
* "usage: KeyBasedFileProcessor -e|-d[-a|ai] file [secretKeyFile passPhrase|pubKeyFile]"
* );
*
* return;
*
* }
*
* if (args[0].equals("-e"))
*
* {
*
* if (args[1].equals("-a") ||args[1].equals("-ai") ||
* args[1].equals("-ia"))
*
* {
*
* encryptFile(args[2] + ".asc",args[2], args[3], true,
* (args[1].indexOf('i') > 0));
*
* }
*
* else if (args[1].equals("-i"))
*
* {
*
* encryptFile(args[2] + ".bpg",args[2], args[3], false, true);
*
* }
*
* else
*
* {
*
* encryptFile(args[1] + ".bpg",args[1], args[2], false, false);
*
* }
*
* }
*
* else if (args[0].equals("-d"))
*
* {
*
* //modify 20160520 set outFileName
*
* decryptFile(args[1], args[2],args[3].toCharArray(), args[4]);
*
* }
*
* else
*
* {
*
* System.err.println(
* "usage: KeyBasedFileProcessor -d|-e[-a|ai] file [secretKeyFile passPhrase|pubKeyFile]"
* );
*
* }
*/
}
}
package com.pgp.iquant;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
importjava.security.NoSuchProviderException;
import java.util.Collection;
import java.util.Iterator;
importorg.bouncycastle.openpgp.PGPCompressedDataGenerator;
import org.bouncycastle.openpgp.PGPException;
importorg.bouncycastle.openpgp.PGPLiteralData;
importorg.bouncycastle.openpgp.PGPPrivateKey;
importorg.bouncycastle.openpgp.PGPPublicKey;
importorg.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
importorg.bouncycastle.openpgp.PGPSecretKey;
importorg.bouncycastle.openpgp.PGPSecretKeyRing;
importorg.bouncycastle.openpgp.PGPSecretKeyRingCollection;
import org.bouncycastle.openpgp.PGPUtil;
importorg.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
importorg.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
importorg.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
class PGPExampleUtil
{
static byte[] compressFile(String fileName, int algorithm) throwsIOException
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
PGPCompressedDataGenerator comData = newPGPCompressedDataGenerator(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 tokeyID 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
*/
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));
}
static PGPPublicKey readPublicKey(String fileName) throws IOException,PGPException
{
InputStream keyIn = new BufferedInputStream(newFileInputStream(fileName));
PGPPublicKey pubKey =readPublicKey(keyIn);
keyIn.close();
return pubKey;
}
/**
* A simple routine that opens a key ring file and loads the firstavailable key
* suitable for encryption.
*
* @param input data stream containing the public key data
* @return the first public key found.
* @throws IOException
* @throws PGPException
*/
static PGPPublicKey readPublicKey(InputStream input) throws IOException,PGPException
{
PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(
PGPUtil.getDecoderStream(input), new JcaKeyFingerprintCalculator());
//
// we just loop through the collection tillwe find a key suitable for encryption, in the real
// world you would probably want to be abit smarter about this.
//
Iterator keyRingIter = pgpPub.getKeyRings();
while (keyRingIter.hasNext())
{
PGPPublicKeyRing keyRing = (PGPPublicKeyRing)keyRingIter.next();
Iterator keyIter = keyRing.getPublicKeys();
while (keyIter.hasNext())
{
PGPPublicKey key =(PGPPublicKey)keyIter.next();
if (key.isEncryptionKey())
{
return key;
}
}
}
throw newIllegalArgumentException("Can’t find encryption key in key ring.");
}
static PGPSecretKey readSecretKey(String fileName) throws IOException,PGPException
{
InputStream keyIn = new BufferedInputStream(newFileInputStream(fileName));
PGPSecretKey secKey = readSecretKey(keyIn);
keyIn.close();
return secKey;
}
/**
* A simple routine that opens a key ring file and loads the firstavailable 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.
*/
static PGPSecretKey readSecretKey(InputStream input) throws IOException,PGPException
{
PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(
PGPUtil.getDecoderStream(input), new JcaKeyFingerprintCalculator());
//
// we just loop through the collection tillwe find a key suitable for encryption, in the real
// world you would probably want to be abit smarter about this.
//
Iterator keyRingIter = pgpSec.getKeyRings();
while (keyRingIter.hasNext())
{
PGPSecretKeyRing keyRing = (PGPSecretKeyRing)keyRingIter.next();
Iterator keyIter = keyRing.getSecretKeys();
while (keyIter.hasNext())
{
PGPSecretKey key =(PGPSecretKey)keyIter.next();
if (key.isSigningKey())
{
return key;
}
}
}
throw new IllegalArgumentException("Can’t find signing key in keyring.");
}
}
参考: http://www.itozi.net/67300.html
jar 包已上传,另见
http://download.csdn.net/detail/qing_mei_xiu/9623342