gpt4 book ai didi

java - 如何解密已签名的 pgp 加密文件?

转载 作者:搜寻专家 更新时间:2023-11-01 01:37:58 25 4
gpt4 key购买 nike

如何使用 BouncyCaSTLe Java API 解密和验证使用 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);
}

关于java - 如何解密已签名的 pgp 加密文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6827725/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com