java解码pgp_java – 如何解密签名的pgp加密文件?

加密代码:

private static void encryptFile(OutputStream out, String fileName, PGPPublicKey encKey, PGPSecretKey pgpSec, boolean armor, boolean withIntegrityCheck, char[] pass) throws IOException, NoSuchProviderException {

if (armor) {

out = new ArmoredOutputStream(out);

}

try {

PGPEncryptedDataGenerator encGen =

new PGPEncryptedDataGenerator(

new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(withIntegrityCheck).setSecureRandom(

new SecureRandom())

.setProvider("BC"));

encGen.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(encKey).setProvider("BC"));

OutputStream encryptedOut = encGen.open(out, new byte[BUFFER_SIZE]);

PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(PGPCompressedData.ZIP);

OutputStream compressedData = comData.open(encryptedOut);

//OutputStream compressedData = encryptedOut;

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);

Iterator it = pgpSec.getPublicKey().getUserIDs();

if (it.hasNext()) {

PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();

spGen.setSignerUserID(false, (String) it.next());

sGen.setHashedSubpackets(spGen.generate());

}

//BCPGOutputStream bOut = new BCPGOutputStream(compressedData);

sGen.generateOnePassVersion(false).encode(compressedData); // bOut

File file = new File(fileName);

PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator();

OutputStream lOut = lGen.open(compressedData, PGPLiteralData.BINARY, file.getName(), new Date(),

new byte[BUFFER_SIZE]); //bOut

FileInputStream fIn = new FileInputStream(file);

int ch;

while ((ch = fIn.read()) >= 0) {

lOut.write(ch);

sGen.update((byte) ch);

}

fIn.close();

lOut.close();

lGen.close();

sGen.generate().encode(compressedData);

//bOut.close();

comData.close();

compressedData.close();

encryptedOut.close();

encGen.close();

if (armor) {

out.close();

}

} catch (PGPException e) {

System.err.println(e);

if (e.getUnderlyingException() != null) {

e.getUnderlyingException().printStackTrace();

}

} catch (SignatureException e) {

System.err.println(e);

}

}

解密代码:

public static void decryptFile(InputStream in, InputStream keyIn, char[] passwd, OutputStream fOut, InputStream publicKeyIn) throws IOException, NoSuchProviderException, SignatureException,

PGPException {

in = PGPUtil.getDecoderStream(in);

PGPObjectFactory pgpF = new PGPObjectFactory(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> it = enc.getEncryptedDataObjects();

PGPPrivateKey sKey = null;

PGPPublicKeyEncryptedData pbe = null;

PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(keyIn));

while (sKey == null && it.hasNext()) {

pbe = (PGPPublicKeyEncryptedData) it.next();

sKey = PGPTools.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 PGPObjectFactory(clear);

Object message = null;

PGPOnePassSignatureList onePassSignatureList = null;

PGPSignatureList signatureList = null;

PGPCompressedData compressedData = null;

message = plainFact.nextObject();

ByteArrayOutputStream actualOutput = new ByteArrayOutputStream();

while (message != null) {

log.trace(message.toString());

if (message instanceof PGPCompressedData) {

compressedData = (PGPCompressedData) message;

plainFact = new PGPObjectFactory(compressedData.getDataStream());

message = plainFact.nextObject();

}

if (message instanceof PGPLiteralData) {

// have to read it and keep it somewhere.

Streams.pipeAll(((PGPLiteralData) message).getInputStream(), actualOutput);

} else if (message instanceof PGPOnePassSignatureList) {

onePassSignatureList = (PGPOnePassSignatureList) message;

} else if (message instanceof PGPSignatureList) {

signatureList = (PGPSignatureList) message;

} else {

throw new PGPException("message unknown message type.");

}

message = plainFact.nextObject();

}

actualOutput.close();

PGPPublicKey publicKey = null;

byte[] output = actualOutput.toByteArray();

if (onePassSignatureList == null || signatureList == null) {

throw new PGPException("Poor PGP. Signatures not found.");

} else {

for (int i = 0; i < onePassSignatureList.size(); i++) {

PGPOnePassSignature ops = onePassSignatureList.get(0);

log.trace("verifier : " + ops.getKeyID());

PGPPublicKeyRingCollection pgpRing = new PGPPublicKeyRingCollection(

PGPUtil.getDecoderStream(publicKeyIn));

publicKey = pgpRing.getPublicKey(ops.getKeyID());

if (publicKey != null) {

ops.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), publicKey);

ops.update(output);

PGPSignature signature = signatureList.get(i);

if (ops.verify(signature)) {

Iterator> userIds = publicKey.getUserIDs();

while (userIds.hasNext()) {

String userId = (String) userIds.next();

log.trace("Signed by {}", userId);

}

log.trace("Signature verified");

} else {

throw new SignatureException("Signature verification failed");

}

}

}

}

if (pbe.isIntegrityProtected() && !pbe.verify()) {

throw new PGPException("Data is integrity protected but integrity is lost.");

} else if (publicKey == null) {

throw new SignatureException("Signature not found");

} else {

fOut.write(output);

fOut.flush();

fOut.close();

}

}

作为参考,这是PGPTools.findSecretKey所做的:

public static PGPPrivateKey findSecretKey(InputStream keyIn, long keyID, char[] pass)

throws IOException, PGPException {

PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(keyIn));

PGPSecretKey pgpSecKey = pgpSec.getSecretKey(keyID);

if (pgpSecKey == null) return null;

PBESecretKeyDecryptor decryptor = new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass);

return pgpSecKey.extractPrivateKey(decryptor);

}


版权声明:本文为weixin_42325867原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。