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

本文提供了使用Java解密和签名PGP加密文件的详细步骤。首先展示了一个加密文件的代码示例,使用PGPEncryptedDataGenerator进行加密,并通过PGPPrivateKey和PGPSignatureGenerator进行签名。接着,解释了解密过程,通过PGPUtil.getDecoderStream读取文件,使用PGPTools.findSecretKey找到相应的私钥,最后通过PGPPublicKeyEncryptedData进行解密和验证签名。
摘要由CSDN通过智能技术生成

加密代码:

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

}

要在Java解密通过PostgreSQL的pgp_sym_encrypt函数加密的数据,您需要使用Bouncy Castle库来实现PGP加密算法。以下是步骤: 1. 首先,您需要将加密的数据从PostgreSQL中检索出来。您可以使用JDBC驱动程序从PostgreSQL数据库中查询数据并将其存储在一个字节数组中。 2. 接下来,您需要创建一个PGPSecretKeyRingCollection对象,该对象包含用于解密数据的私钥。您可以从文件中读取这些私钥,也可以从KeyStore中读取它们。 3. 然后,您需要使用Bouncy Castle库中的PGPUtil类来创建一个PGPObjectFactory对象。您可以使用该对象将加密的数据转换为PGP数据包对象。 4. 接下来,您需要使用PGPObjectFactory对象中的PGPDataDecryptorFactory对象进行解密。您可以使用Bouncy Castle库中的JcePublicKeyDataDecryptorFactoryBuilder类来创建PGPDataDecryptorFactory对象。 5. 最后,您可以使用PGPDataDecryptorFactory对象对PGP数据包对象进行解密,并将结果存储在一个字节数组中。 以下是一个示例代码,演示如何在Java解密通过PostgreSQL的pgp_sym_encrypt函数加密的数据: ```java import java.io.ByteArrayInputStream; import java.io.InputStream; import java.security.Security; import java.util.Iterator; import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory; import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder; import org.postgresql.util.PGobject; public class PgpDecrypt { public static byte[] decrypt(PGobject pgpEncryptedData, PGPSecretKeyRingCollection secretKeys) throws Exception { Security.addProvider(new BouncyCastleProvider()); byte[] encryptedData = (byte[]) pgpEncryptedData.getValue(); InputStream inputStream = new ByteArrayInputStream(encryptedData); BCPGInputStream bcpgInputStream = new BCPGInputStream(inputStream); PGPObjectFactory pgpObjectFactory = new PGPObjectFactory(bcpgInputStream); Object pgpObject = pgpObjectFactory.nextObject(); if (pgpObject instanceof PGPSecretKeyRing) { PGPSecretKeyRing secretKeyRing = (PGPSecretKeyRing) pgpObject; Iterator<PGPSecretKey> secretKeysIterator = secretKeyRing.getSecretKeys(); while (secretKeysIterator.hasNext()) { PGPSecretKey secretKey = secretKeysIterator.next(); PublicKeyDataDecryptorFactory decryptorFactory = new JcePublicKeyDataDecryptorFactoryBuilder() .setProvider("BC").build(secretKey.extractPrivateKey(null)); InputStream decryptedStream = secretKey.extractPrivateKey(null) .decryptStream(pgpObjectFactory.nextObject().getDataStream(), decryptorFactory); byte[] decryptedData = new byte[decryptedStream.available()]; decryptedStream.read(decryptedData); return decryptedData; } } throw new Exception("No secret key found to decrypt PGP data"); } } ``` 该示例代码从一个PGP加密的PGobject对象和一个PGPSecretKeyRingCollection对象中获取加密数据和私钥,然后将加密数据解密并返回解密后的数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值