Pgp 签名+加密然后解密+验证
Pgp sign+encrypt then decrypt+verify
在进行符号加密然后解密和验证时,我在验证时不断在流中获取未知对象。消息完整性检查已通过,但是当我尝试在解密后的下一行中进行验证时,出现了上述错误。
private static void encryptFile(
String outFileName,
OutputStream out,
String fileName,
PGPPublicKey encKey,
String sKeyFileName,
char[] passPhrase,
boolean armor,
boolean withIntegrityCheck)
throws Exception
{
if (armor)
{
out = new ArmoredOutputStream(out);
}
try
{
byte[] bytes = PGPKeyUtil.compressFile(fileName, CompressionAlgorithmTags.ZIP);
PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(
PGPEncryptedData.CAST5, withIntegrityCheck, new SecureRandom(), "BC");
encGen.addMethod(encKey);
OutputStream cOut = encGen.open(out, bytes.length);
cOut.write(bytes);
cOut.close();
out.close();
cOut.close();
if (armor)
{
out.close();
}
encGen.close();
}
catch (PGPException e)
{
System.err.println(e);
if (e.getUnderlyingException() != null)
{
e.getUnderlyingException().printStackTrace();
}
}
}
public static void signFile(
String fileName,
InputStream keyIn,
OutputStream out,
char[] pass,
boolean armor)
throws IOException, NoSuchAlgorithmException, NoSuchProviderException, PGPException, SignatureException
{
if (armor)
{
out = new ArmoredOutputStream(out);
}
PGPSecretKey pgpSec = readSecretKey(keyIn);
PGPPrivateKey pgpPrivKey = pgpSec.extractPrivateKey(pass, "BC");
PGPSignatureGenerator sGen = new PGPSignatureGenerator(pgpSec.getPublicKey().getAlgorithm(), PGPUtil.SHA1, "BC");
sGen.initSign(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);
Iterator it = pgpSec.getPublicKey().getUserIDs();
if (it.hasNext())
{
PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
spGen.setSignerUserID(false, (String)it.next());
sGen.setHashedSubpackets(spGen.generate());
}
PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator(
PGPCompressedData.ZLIB);
BCPGOutputStream bOut = new BCPGOutputStream(cGen.open(out));
sGen.generateOnePassVersion(false).encode(bOut);
File file = new File(fileName);
PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator();
OutputStream lOut = lGen.open(bOut, PGPLiteralData.BINARY, file);
FileInputStream fIn = new FileInputStream(file);
int ch = 0;
while ((ch = fIn.read()) >= 0)
{
lOut.write(ch);
sGen.update((byte)ch);
}
lGen.close();
sGen.generate().encode(bOut);
cGen.close();
bOut.close();
fIn.close();
lOut.close();
if (armor)
{
out.close();
}
System.out.println("Successfully signed");
}
首先我使用 signFile 签名,然后我使用加密方法加密文件。
我测试了你的代码
加密并签署我的一些文本文件,然后再解密。
那我解密的时候也报错
消息是-
unknown object in stream: 56
java.io.IOException: unknown object in stream: 56
at org.bouncycastle.openpgp.PGPObjectFactory.nextObject(Unknown Source)
at FileEncryptTest._decrypt(FileEncryptTest.java:205)
at FileEncryptTest.decryptFile(FileEncryptTest.java:170)
at FileEncryptTest.main(FileEncryptTest.java:157)
我不确定与你的消息是否相同,但 signFile 方法必须如下所示,
private static void signFile(String fileName, InputStream keyIn, OutputStream out, char[] pass, boolean armor)
throws GeneralSecurityException, IOException, PGPException {
if (armor) {
out = new ArmoredOutputStream(out);
}
PGPSecretKey pgpSec = readSecretKey(keyIn);
PGPPrivateKey pgpPrivKey = pgpSec
.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(pass));
PGPSignatureGenerator sGen = new PGPSignatureGenerator(
new JcaPGPContentSignerBuilder(pgpSec.getPublicKey().getAlgorithm(), PGPUtil.SHA1).setProvider("BC"));
sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);
BCPGOutputStream bOut = new BCPGOutputStream(out);
InputStream fIn = new BufferedInputStream(new FileInputStream(fileName));
byte[] buf = new byte[1024];
int len;
while ((len = fIn.read(buf)) > 0) {
sGen.update(buf, 0, len);
}
//int ch;
//while ((ch = fIn.read()) >= 0) {
// sGen.update((byte) ch);
//}
fIn.close();
sGen.generate().encode(bOut);
if (armor) {
out.close();
}
out.close();
bOut.close();
}
我的 bouncycastle 库正是 bcpg-jdk15on-158.jar - 最新的。
因此,API 的某些部分代码可能有所不同。
我在我的主要方法中添加了它。
首先,我的私有&public密钥文件声明。
private static File publicKeyFile = new File("resource/PGP1D0.pkr");
private static File privateKeyFile = new File("resource/PGP1D0.skr");
private static String privateKeyPassword = "passphrase";
当 isEncrypt 为真时,签名并加密文件,否则解密文件。
当 isEncrypt 标志为真时,原始文件在加密签名后为 tile_doc.in 和 tile_doc.signed.in,然后让标志为假和 运行。
在资源文件夹中可以看到tile_doc.out文件
private static final boolean isEncrypt = false;
public static void main(String[] args) {
Security.addProvider(new BouncyCastleProvider());
String outFileName = "resource/tile_doc.signed.in";
String recoverFile = "resource/tile_doc.out";
OutputStream out = null;
InputStream keyIn = null;
InputStream outFileIn = null;
String fileName = "resource/tile_doc.in";
PGPPublicKey encKey = null;
char[] passPhrase = privateKeyPassword.toCharArray();
boolean armor = false;
boolean withIntegrityCheck = true;
if (isEncrypt) {
try {
keyIn = new BufferedInputStream(new FileInputStream(privateKeyFile));
out = new BufferedOutputStream(new FileOutputStream(outFileName));
encKey = readPublicKeyFromCol(new FileInputStream(publicKeyFile));
//
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
signFile(fileName, keyIn, out, passPhrase, armor);
out = new BufferedOutputStream(new FileOutputStream(outFileName));
} catch (GeneralSecurityException | IOException | PGPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
encryptFile(outFileName, out, fileName, encKey, passPhrase, armor, withIntegrityCheck);
} else {
try {
keyIn = new BufferedInputStream(new FileInputStream(privateKeyFile));
outFileIn = new BufferedInputStream(new FileInputStream(outFileName));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
decryptFile(outFileIn, keyIn, passPhrase, recoverFile);
}
}
然后,我的 decryptFile 方法有两部分,
一个是带有二进制内容的 base64 编码,
另一个是主要的解密部分。
public static void decryptFile(InputStream outFileIn, InputStream privKeyStream, char[] passPhrase, String outFileName) {
// ----- Decrypt the file
try {
ByteBuffer buf = ByteBuffer.allocate(1024 * 10);
byte[] read = new byte[1024];
while (outFileIn.read(read, 0, 1024) != -1) {
buf.put(read);
}
BASE64Encoder en = new BASE64Encoder();
String temp = en.encode(buf.array());
// System.out.println("Temp: " + temp);
byte[] newB = null;
BASE64Decoder en1 = new BASE64Decoder();
try {
newB = en1.decodeBuffer(temp);
} catch (Exception e) {
System.out.println("Exception: " + e);
}
ByteArrayInputStream bais = new ByteArrayInputStream(newB);
decryptIt(bais, privKeyStream, passPhrase, outFileName);
} catch (Exception e1) {
e1.printStackTrace();
}
}
这是最新版 pg Bouncy Castle Cryptography Library 1.58 的完整源代码。
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.security.GeneralSecurityException;
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.BCPGOutputStream;
import org.bouncycastle.bcpg.HashAlgorithmTags;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPCompressedData;
import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
import org.bouncycastle.openpgp.PGPEncryptedData;
import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
import org.bouncycastle.openpgp.PGPEncryptedDataList;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPLiteralData;
import org.bouncycastle.openpgp.PGPLiteralDataGenerator;
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.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureGenerator;
import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator;
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator;
import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory;
import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
//
public class FileEncryptTest {
private static File publicKeyFile = new File("resource/PGP1D0.pkr");
private static File privateKeyFile = new File("resource/PGP1D0.skr");
private static String privateKeyPassword = "passphrase";
private static final boolean isEncrypt = false;
public static void main(String[] args) {
Security.addProvider(new BouncyCastleProvider());
String outFileName = "resource/tile_doc.signed.in";
String recoverFile = "resource/tile_doc.out";
OutputStream out = null;
InputStream keyIn = null;
InputStream outFileIn = null;
String fileName = "resource/tile_doc.in";
PGPPublicKey encKey = null;
char[] passPhrase = privateKeyPassword.toCharArray();
boolean armor = false;
boolean withIntegrityCheck = true;
if (isEncrypt) {
try {
keyIn = new BufferedInputStream(new FileInputStream(privateKeyFile));
out = new BufferedOutputStream(new FileOutputStream(outFileName));
encKey = readPublicKeyFromCol(new FileInputStream(publicKeyFile));
//
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
signFile(fileName, keyIn, out, passPhrase, armor);
out = new BufferedOutputStream(new FileOutputStream(outFileName));
} catch (GeneralSecurityException | IOException | PGPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
encryptFile(outFileName, out, fileName, encKey, passPhrase, armor, withIntegrityCheck);
} else {
try {
keyIn = new BufferedInputStream(new FileInputStream(privateKeyFile));
outFileIn = new BufferedInputStream(new FileInputStream(outFileName));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
decryptFile(outFileIn, keyIn, passPhrase, recoverFile);
}
}
static final KeyFingerPrintCalculator FP_CALC = new BcKeyFingerprintCalculator();
private static PGPPublicKey readPublicKeyFromCol(InputStream in) throws Exception {
PGPPublicKeyRing pkRing = null;
// PGPPublicKeyRingCollection pkCol = new PGPPublicKeyRingCollection(in,
// FP_CALC);
PGPPublicKeyRingCollection pkCol = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(in), FP_CALC);
System.out.println("key ring size=" + pkCol.size());
Iterator it = pkCol.getKeyRings();
while (it.hasNext()) {
pkRing = (PGPPublicKeyRing) it.next();
Iterator pkIt = pkRing.getPublicKeys();
while (pkIt.hasNext()) {
PGPPublicKey key = (PGPPublicKey) pkIt.next();
System.out.println("Encryption key = " + key.isEncryptionKey() + ", Master key = " + key.isMasterKey());
if (key.isEncryptionKey())
return key;
}
}
return null;
}
public static void decryptFile(InputStream outFileIn, InputStream privKeyStream, char[] passPhrase, String outFileName) {
// ----- Decrypt the file
try {
ByteBuffer buf = ByteBuffer.allocate(1024 * 10);
byte[] read = new byte[1024];
while (outFileIn.read(read, 0, 1024) != -1) {
buf.put(read);
}
BASE64Encoder en = new BASE64Encoder();
String temp = en.encode(buf.array());
// System.out.println("Temp: " + temp);
byte[] newB = null;
BASE64Decoder en1 = new BASE64Decoder();
try {
newB = en1.decodeBuffer(temp);
} catch (Exception e) {
System.out.println("Exception: " + e);
}
ByteArrayInputStream bais = new ByteArrayInputStream(newB);
decryptIt(bais, privKeyStream, passPhrase, outFileName);
} catch (Exception e1) {
e1.printStackTrace();
}
}
private static PGPPrivateKey findSecretKey(InputStream keyIn, long keyID, char[] pass)
throws IOException, PGPException, NoSuchProviderException {
PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(keyIn), FP_CALC);
PGPSecretKey pgpSecKey = pgpSec.getSecretKey(keyID);
if (pgpSecKey == null) {
return null;
}
PBESecretKeyDecryptor secretKeyDecryptor = new JcePBESecretKeyDecryptorBuilder()
.setProvider(BouncyCastleProvider.PROVIDER_NAME).build(pass);
return pgpSecKey.extractPrivateKey(secretKeyDecryptor);
}
private static void decryptIt(InputStream in, InputStream keyIn, char[] passwd, String filename) throws Exception {
in = PGPUtil.getDecoderStream(in);
try {
PGPObjectFactory pgpF = new PGPObjectFactory(in, FP_CALC);
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;
while (sKey == null && it.hasNext()) {
pbe = (PGPPublicKeyEncryptedData) it.next();
System.out.println("pbe id=" + pbe.getKeyID());
sKey = findSecretKey(keyIn, pbe.getKeyID(), passwd);
}
if (sKey == null) {
throw new IllegalArgumentException("secret key for message not found.");
}
// InputStream clear = pbe.getDataStream(sKey, "BC");
InputStream clear = pbe.getDataStream(new BcPublicKeyDataDecryptorFactory(sKey));
PGPObjectFactory plainFact = new PGPObjectFactory(clear, FP_CALC);
Object message = plainFact.nextObject();
if (message instanceof PGPCompressedData) {
PGPCompressedData cData = (PGPCompressedData) message;
PGPObjectFactory pgpFact = new PGPObjectFactory(cData.getDataStream(), FP_CALC);
message = pgpFact.nextObject();
}
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(filename));
if (message instanceof PGPLiteralData) {
PGPLiteralData ld = (PGPLiteralData) message;
InputStream unc = ld.getInputStream();
int ch;
while ((ch = unc.read()) >= 0) {
bout.write(ch);
}
} 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.");
}
bout.flush();
bout.close();
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();
}
}
}
private static void encryptFile(String outFileName, OutputStream out, String fileName, PGPPublicKey encKey,
char[] passPhrase, boolean armor, boolean withIntegrityCheck) {
if (armor) {
out = new ArmoredOutputStream(out);
}
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
System.out.println("creating comData...");
// get the data from the original file
PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(PGPCompressedDataGenerator.ZIP);
try {
PGPUtil.writeFileToLiteralData(comData.open(bOut), PGPLiteralData.BINARY, new File(fileName));
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
comData.close();
} catch (IOException e) {
}
}
PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(
new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(withIntegrityCheck)
.setSecureRandom(new SecureRandom()).setProvider("BC"));
encGen.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(encKey).setProvider("BC"));
byte[] bytes = bOut.toByteArray();
OutputStream cOut;
try {
cOut = encGen.open(out, bytes.length);
cOut.write(bytes);
} catch (IOException | PGPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
encGen.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 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.
*/
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 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 key ring.");
}
private static void signFile(String fileName, InputStream keyIn, OutputStream out, char[] pass, boolean armor)
throws GeneralSecurityException, IOException, PGPException {
if (armor) {
out = new ArmoredOutputStream(out);
}
PGPSecretKey pgpSec = readSecretKey(keyIn);
PGPPrivateKey pgpPrivKey = pgpSec
.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(pass));
PGPSignatureGenerator sGen = new PGPSignatureGenerator(
new JcaPGPContentSignerBuilder(pgpSec.getPublicKey().getAlgorithm(), PGPUtil.SHA1).setProvider("BC"));
sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);
BCPGOutputStream bOut = new BCPGOutputStream(out);
InputStream fIn = new BufferedInputStream(new FileInputStream(fileName));
byte[] buf = new byte[1024];
int len;
while ((len = fIn.read(buf)) > 0) {
sGen.update(buf, 0, len);
}
//int ch;
//while ((ch = fIn.read()) >= 0) {
// sGen.update((byte) ch);
//}
fIn.close();
sGen.generate().encode(bOut);
if (armor) {
out.close();
}
out.close();
bOut.close();
}
}
最后,public/private 密钥文件生成为 rsa。
我从RSAKeyPairGenerator.java.
那里借用了代码
来源如下
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.security.SignatureException;
import java.util.Date;
import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.bcpg.HashAlgorithmTags;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPEncryptedData;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPKeyPair;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.operator.PGPDigestCalculator;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair;
import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder;
public class FileEncDec {
private static File publicKeyFile = new File("resource/PGP1D0.pkr");
private static File privateKeyFile = new File("resource/PGP1D0.skr");
private static String privateKeyPassword = "passphrase";
private static String identity = "tommybee";
private static boolean isAll = true;
private static void exportKeyPair(OutputStream secretOut, OutputStream publicOut, KeyPair pair, String identity,
char[] passPhrase, boolean armor)
throws IOException, InvalidKeyException, NoSuchProviderException, SignatureException, PGPException {
if (armor) {
secretOut = new ArmoredOutputStream(secretOut);
}
PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA1);
PGPKeyPair keyPair = new JcaPGPKeyPair(PGPPublicKey.RSA_GENERAL, pair, new Date());
PGPSecretKey secretKey = new PGPSecretKey(PGPSignature.DEFAULT_CERTIFICATION, keyPair, identity, sha1Calc, null,
null, new JcaPGPContentSignerBuilder(keyPair.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1),
new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.CAST5, sha1Calc).setProvider("BC")
.build(passPhrase));
secretKey.encode(secretOut);
secretOut.close();
if (armor) {
publicOut = new ArmoredOutputStream(publicOut);
}
PGPPublicKey key = secretKey.getPublicKey();
key.encode(publicOut);
publicOut.close();
}
public static void main(String[] args) throws Exception {
Security.addProvider(new BouncyCastleProvider());
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC");
kpg.initialize(1024);
KeyPair kp = kpg.generateKeyPair();
if (isAll) {
FileOutputStream out1 = new FileOutputStream(privateKeyFile);
FileOutputStream out2 = new FileOutputStream(publicKeyFile);
exportKeyPair(out1, out2, kp, identity, privateKeyPassword.toCharArray(), true);
} else {
FileOutputStream out1 = new FileOutputStream(privateKeyFile);
FileOutputStream out2 = new FileOutputStream(publicKeyFile);
exportKeyPair(out1, out2, kp, identity, privateKeyPassword.toCharArray(), false);
}
}
}
希望对您有所帮助。
此致,
在进行符号加密然后解密和验证时,我在验证时不断在流中获取未知对象。消息完整性检查已通过,但是当我尝试在解密后的下一行中进行验证时,出现了上述错误。
private static void encryptFile(
String outFileName,
OutputStream out,
String fileName,
PGPPublicKey encKey,
String sKeyFileName,
char[] passPhrase,
boolean armor,
boolean withIntegrityCheck)
throws Exception
{
if (armor)
{
out = new ArmoredOutputStream(out);
}
try
{
byte[] bytes = PGPKeyUtil.compressFile(fileName, CompressionAlgorithmTags.ZIP);
PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(
PGPEncryptedData.CAST5, withIntegrityCheck, new SecureRandom(), "BC");
encGen.addMethod(encKey);
OutputStream cOut = encGen.open(out, bytes.length);
cOut.write(bytes);
cOut.close();
out.close();
cOut.close();
if (armor)
{
out.close();
}
encGen.close();
}
catch (PGPException e)
{
System.err.println(e);
if (e.getUnderlyingException() != null)
{
e.getUnderlyingException().printStackTrace();
}
}
}
public static void signFile(
String fileName,
InputStream keyIn,
OutputStream out,
char[] pass,
boolean armor)
throws IOException, NoSuchAlgorithmException, NoSuchProviderException, PGPException, SignatureException
{
if (armor)
{
out = new ArmoredOutputStream(out);
}
PGPSecretKey pgpSec = readSecretKey(keyIn);
PGPPrivateKey pgpPrivKey = pgpSec.extractPrivateKey(pass, "BC");
PGPSignatureGenerator sGen = new PGPSignatureGenerator(pgpSec.getPublicKey().getAlgorithm(), PGPUtil.SHA1, "BC");
sGen.initSign(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);
Iterator it = pgpSec.getPublicKey().getUserIDs();
if (it.hasNext())
{
PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
spGen.setSignerUserID(false, (String)it.next());
sGen.setHashedSubpackets(spGen.generate());
}
PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator(
PGPCompressedData.ZLIB);
BCPGOutputStream bOut = new BCPGOutputStream(cGen.open(out));
sGen.generateOnePassVersion(false).encode(bOut);
File file = new File(fileName);
PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator();
OutputStream lOut = lGen.open(bOut, PGPLiteralData.BINARY, file);
FileInputStream fIn = new FileInputStream(file);
int ch = 0;
while ((ch = fIn.read()) >= 0)
{
lOut.write(ch);
sGen.update((byte)ch);
}
lGen.close();
sGen.generate().encode(bOut);
cGen.close();
bOut.close();
fIn.close();
lOut.close();
if (armor)
{
out.close();
}
System.out.println("Successfully signed");
}
首先我使用 signFile 签名,然后我使用加密方法加密文件。
我测试了你的代码
加密并签署我的一些文本文件,然后再解密。
那我解密的时候也报错
消息是-
unknown object in stream: 56
java.io.IOException: unknown object in stream: 56
at org.bouncycastle.openpgp.PGPObjectFactory.nextObject(Unknown Source)
at FileEncryptTest._decrypt(FileEncryptTest.java:205)
at FileEncryptTest.decryptFile(FileEncryptTest.java:170)
at FileEncryptTest.main(FileEncryptTest.java:157)
我不确定与你的消息是否相同,但 signFile 方法必须如下所示,
private static void signFile(String fileName, InputStream keyIn, OutputStream out, char[] pass, boolean armor)
throws GeneralSecurityException, IOException, PGPException {
if (armor) {
out = new ArmoredOutputStream(out);
}
PGPSecretKey pgpSec = readSecretKey(keyIn);
PGPPrivateKey pgpPrivKey = pgpSec
.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(pass));
PGPSignatureGenerator sGen = new PGPSignatureGenerator(
new JcaPGPContentSignerBuilder(pgpSec.getPublicKey().getAlgorithm(), PGPUtil.SHA1).setProvider("BC"));
sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);
BCPGOutputStream bOut = new BCPGOutputStream(out);
InputStream fIn = new BufferedInputStream(new FileInputStream(fileName));
byte[] buf = new byte[1024];
int len;
while ((len = fIn.read(buf)) > 0) {
sGen.update(buf, 0, len);
}
//int ch;
//while ((ch = fIn.read()) >= 0) {
// sGen.update((byte) ch);
//}
fIn.close();
sGen.generate().encode(bOut);
if (armor) {
out.close();
}
out.close();
bOut.close();
}
我的 bouncycastle 库正是 bcpg-jdk15on-158.jar - 最新的。 因此,API 的某些部分代码可能有所不同。
我在我的主要方法中添加了它。
首先,我的私有&public密钥文件声明。
private static File publicKeyFile = new File("resource/PGP1D0.pkr");
private static File privateKeyFile = new File("resource/PGP1D0.skr");
private static String privateKeyPassword = "passphrase";
当 isEncrypt 为真时,签名并加密文件,否则解密文件。 当 isEncrypt 标志为真时,原始文件在加密签名后为 tile_doc.in 和 tile_doc.signed.in,然后让标志为假和 运行。 在资源文件夹中可以看到tile_doc.out文件
private static final boolean isEncrypt = false;
public static void main(String[] args) {
Security.addProvider(new BouncyCastleProvider());
String outFileName = "resource/tile_doc.signed.in";
String recoverFile = "resource/tile_doc.out";
OutputStream out = null;
InputStream keyIn = null;
InputStream outFileIn = null;
String fileName = "resource/tile_doc.in";
PGPPublicKey encKey = null;
char[] passPhrase = privateKeyPassword.toCharArray();
boolean armor = false;
boolean withIntegrityCheck = true;
if (isEncrypt) {
try {
keyIn = new BufferedInputStream(new FileInputStream(privateKeyFile));
out = new BufferedOutputStream(new FileOutputStream(outFileName));
encKey = readPublicKeyFromCol(new FileInputStream(publicKeyFile));
//
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
signFile(fileName, keyIn, out, passPhrase, armor);
out = new BufferedOutputStream(new FileOutputStream(outFileName));
} catch (GeneralSecurityException | IOException | PGPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
encryptFile(outFileName, out, fileName, encKey, passPhrase, armor, withIntegrityCheck);
} else {
try {
keyIn = new BufferedInputStream(new FileInputStream(privateKeyFile));
outFileIn = new BufferedInputStream(new FileInputStream(outFileName));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
decryptFile(outFileIn, keyIn, passPhrase, recoverFile);
}
}
然后,我的 decryptFile 方法有两部分, 一个是带有二进制内容的 base64 编码, 另一个是主要的解密部分。
public static void decryptFile(InputStream outFileIn, InputStream privKeyStream, char[] passPhrase, String outFileName) {
// ----- Decrypt the file
try {
ByteBuffer buf = ByteBuffer.allocate(1024 * 10);
byte[] read = new byte[1024];
while (outFileIn.read(read, 0, 1024) != -1) {
buf.put(read);
}
BASE64Encoder en = new BASE64Encoder();
String temp = en.encode(buf.array());
// System.out.println("Temp: " + temp);
byte[] newB = null;
BASE64Decoder en1 = new BASE64Decoder();
try {
newB = en1.decodeBuffer(temp);
} catch (Exception e) {
System.out.println("Exception: " + e);
}
ByteArrayInputStream bais = new ByteArrayInputStream(newB);
decryptIt(bais, privKeyStream, passPhrase, outFileName);
} catch (Exception e1) {
e1.printStackTrace();
}
}
这是最新版 pg Bouncy Castle Cryptography Library 1.58 的完整源代码。
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.security.GeneralSecurityException;
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.BCPGOutputStream;
import org.bouncycastle.bcpg.HashAlgorithmTags;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPCompressedData;
import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
import org.bouncycastle.openpgp.PGPEncryptedData;
import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
import org.bouncycastle.openpgp.PGPEncryptedDataList;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPLiteralData;
import org.bouncycastle.openpgp.PGPLiteralDataGenerator;
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.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureGenerator;
import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator;
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator;
import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory;
import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
//
public class FileEncryptTest {
private static File publicKeyFile = new File("resource/PGP1D0.pkr");
private static File privateKeyFile = new File("resource/PGP1D0.skr");
private static String privateKeyPassword = "passphrase";
private static final boolean isEncrypt = false;
public static void main(String[] args) {
Security.addProvider(new BouncyCastleProvider());
String outFileName = "resource/tile_doc.signed.in";
String recoverFile = "resource/tile_doc.out";
OutputStream out = null;
InputStream keyIn = null;
InputStream outFileIn = null;
String fileName = "resource/tile_doc.in";
PGPPublicKey encKey = null;
char[] passPhrase = privateKeyPassword.toCharArray();
boolean armor = false;
boolean withIntegrityCheck = true;
if (isEncrypt) {
try {
keyIn = new BufferedInputStream(new FileInputStream(privateKeyFile));
out = new BufferedOutputStream(new FileOutputStream(outFileName));
encKey = readPublicKeyFromCol(new FileInputStream(publicKeyFile));
//
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
signFile(fileName, keyIn, out, passPhrase, armor);
out = new BufferedOutputStream(new FileOutputStream(outFileName));
} catch (GeneralSecurityException | IOException | PGPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
encryptFile(outFileName, out, fileName, encKey, passPhrase, armor, withIntegrityCheck);
} else {
try {
keyIn = new BufferedInputStream(new FileInputStream(privateKeyFile));
outFileIn = new BufferedInputStream(new FileInputStream(outFileName));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
decryptFile(outFileIn, keyIn, passPhrase, recoverFile);
}
}
static final KeyFingerPrintCalculator FP_CALC = new BcKeyFingerprintCalculator();
private static PGPPublicKey readPublicKeyFromCol(InputStream in) throws Exception {
PGPPublicKeyRing pkRing = null;
// PGPPublicKeyRingCollection pkCol = new PGPPublicKeyRingCollection(in,
// FP_CALC);
PGPPublicKeyRingCollection pkCol = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(in), FP_CALC);
System.out.println("key ring size=" + pkCol.size());
Iterator it = pkCol.getKeyRings();
while (it.hasNext()) {
pkRing = (PGPPublicKeyRing) it.next();
Iterator pkIt = pkRing.getPublicKeys();
while (pkIt.hasNext()) {
PGPPublicKey key = (PGPPublicKey) pkIt.next();
System.out.println("Encryption key = " + key.isEncryptionKey() + ", Master key = " + key.isMasterKey());
if (key.isEncryptionKey())
return key;
}
}
return null;
}
public static void decryptFile(InputStream outFileIn, InputStream privKeyStream, char[] passPhrase, String outFileName) {
// ----- Decrypt the file
try {
ByteBuffer buf = ByteBuffer.allocate(1024 * 10);
byte[] read = new byte[1024];
while (outFileIn.read(read, 0, 1024) != -1) {
buf.put(read);
}
BASE64Encoder en = new BASE64Encoder();
String temp = en.encode(buf.array());
// System.out.println("Temp: " + temp);
byte[] newB = null;
BASE64Decoder en1 = new BASE64Decoder();
try {
newB = en1.decodeBuffer(temp);
} catch (Exception e) {
System.out.println("Exception: " + e);
}
ByteArrayInputStream bais = new ByteArrayInputStream(newB);
decryptIt(bais, privKeyStream, passPhrase, outFileName);
} catch (Exception e1) {
e1.printStackTrace();
}
}
private static PGPPrivateKey findSecretKey(InputStream keyIn, long keyID, char[] pass)
throws IOException, PGPException, NoSuchProviderException {
PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(keyIn), FP_CALC);
PGPSecretKey pgpSecKey = pgpSec.getSecretKey(keyID);
if (pgpSecKey == null) {
return null;
}
PBESecretKeyDecryptor secretKeyDecryptor = new JcePBESecretKeyDecryptorBuilder()
.setProvider(BouncyCastleProvider.PROVIDER_NAME).build(pass);
return pgpSecKey.extractPrivateKey(secretKeyDecryptor);
}
private static void decryptIt(InputStream in, InputStream keyIn, char[] passwd, String filename) throws Exception {
in = PGPUtil.getDecoderStream(in);
try {
PGPObjectFactory pgpF = new PGPObjectFactory(in, FP_CALC);
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;
while (sKey == null && it.hasNext()) {
pbe = (PGPPublicKeyEncryptedData) it.next();
System.out.println("pbe id=" + pbe.getKeyID());
sKey = findSecretKey(keyIn, pbe.getKeyID(), passwd);
}
if (sKey == null) {
throw new IllegalArgumentException("secret key for message not found.");
}
// InputStream clear = pbe.getDataStream(sKey, "BC");
InputStream clear = pbe.getDataStream(new BcPublicKeyDataDecryptorFactory(sKey));
PGPObjectFactory plainFact = new PGPObjectFactory(clear, FP_CALC);
Object message = plainFact.nextObject();
if (message instanceof PGPCompressedData) {
PGPCompressedData cData = (PGPCompressedData) message;
PGPObjectFactory pgpFact = new PGPObjectFactory(cData.getDataStream(), FP_CALC);
message = pgpFact.nextObject();
}
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(filename));
if (message instanceof PGPLiteralData) {
PGPLiteralData ld = (PGPLiteralData) message;
InputStream unc = ld.getInputStream();
int ch;
while ((ch = unc.read()) >= 0) {
bout.write(ch);
}
} 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.");
}
bout.flush();
bout.close();
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();
}
}
}
private static void encryptFile(String outFileName, OutputStream out, String fileName, PGPPublicKey encKey,
char[] passPhrase, boolean armor, boolean withIntegrityCheck) {
if (armor) {
out = new ArmoredOutputStream(out);
}
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
System.out.println("creating comData...");
// get the data from the original file
PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(PGPCompressedDataGenerator.ZIP);
try {
PGPUtil.writeFileToLiteralData(comData.open(bOut), PGPLiteralData.BINARY, new File(fileName));
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
comData.close();
} catch (IOException e) {
}
}
PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(
new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(withIntegrityCheck)
.setSecureRandom(new SecureRandom()).setProvider("BC"));
encGen.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(encKey).setProvider("BC"));
byte[] bytes = bOut.toByteArray();
OutputStream cOut;
try {
cOut = encGen.open(out, bytes.length);
cOut.write(bytes);
} catch (IOException | PGPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
encGen.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 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.
*/
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 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 key ring.");
}
private static void signFile(String fileName, InputStream keyIn, OutputStream out, char[] pass, boolean armor)
throws GeneralSecurityException, IOException, PGPException {
if (armor) {
out = new ArmoredOutputStream(out);
}
PGPSecretKey pgpSec = readSecretKey(keyIn);
PGPPrivateKey pgpPrivKey = pgpSec
.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(pass));
PGPSignatureGenerator sGen = new PGPSignatureGenerator(
new JcaPGPContentSignerBuilder(pgpSec.getPublicKey().getAlgorithm(), PGPUtil.SHA1).setProvider("BC"));
sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);
BCPGOutputStream bOut = new BCPGOutputStream(out);
InputStream fIn = new BufferedInputStream(new FileInputStream(fileName));
byte[] buf = new byte[1024];
int len;
while ((len = fIn.read(buf)) > 0) {
sGen.update(buf, 0, len);
}
//int ch;
//while ((ch = fIn.read()) >= 0) {
// sGen.update((byte) ch);
//}
fIn.close();
sGen.generate().encode(bOut);
if (armor) {
out.close();
}
out.close();
bOut.close();
}
}
最后,public/private 密钥文件生成为 rsa。 我从RSAKeyPairGenerator.java.
那里借用了代码来源如下
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.security.SignatureException;
import java.util.Date;
import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.bcpg.HashAlgorithmTags;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPEncryptedData;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPKeyPair;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.operator.PGPDigestCalculator;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair;
import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder;
public class FileEncDec {
private static File publicKeyFile = new File("resource/PGP1D0.pkr");
private static File privateKeyFile = new File("resource/PGP1D0.skr");
private static String privateKeyPassword = "passphrase";
private static String identity = "tommybee";
private static boolean isAll = true;
private static void exportKeyPair(OutputStream secretOut, OutputStream publicOut, KeyPair pair, String identity,
char[] passPhrase, boolean armor)
throws IOException, InvalidKeyException, NoSuchProviderException, SignatureException, PGPException {
if (armor) {
secretOut = new ArmoredOutputStream(secretOut);
}
PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA1);
PGPKeyPair keyPair = new JcaPGPKeyPair(PGPPublicKey.RSA_GENERAL, pair, new Date());
PGPSecretKey secretKey = new PGPSecretKey(PGPSignature.DEFAULT_CERTIFICATION, keyPair, identity, sha1Calc, null,
null, new JcaPGPContentSignerBuilder(keyPair.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1),
new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.CAST5, sha1Calc).setProvider("BC")
.build(passPhrase));
secretKey.encode(secretOut);
secretOut.close();
if (armor) {
publicOut = new ArmoredOutputStream(publicOut);
}
PGPPublicKey key = secretKey.getPublicKey();
key.encode(publicOut);
publicOut.close();
}
public static void main(String[] args) throws Exception {
Security.addProvider(new BouncyCastleProvider());
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC");
kpg.initialize(1024);
KeyPair kp = kpg.generateKeyPair();
if (isAll) {
FileOutputStream out1 = new FileOutputStream(privateKeyFile);
FileOutputStream out2 = new FileOutputStream(publicKeyFile);
exportKeyPair(out1, out2, kp, identity, privateKeyPassword.toCharArray(), true);
} else {
FileOutputStream out1 = new FileOutputStream(privateKeyFile);
FileOutputStream out2 = new FileOutputStream(publicKeyFile);
exportKeyPair(out1, out2, kp, identity, privateKeyPassword.toCharArray(), false);
}
}
}
希望对您有所帮助。 此致,