英文:
How to Extract PGP public key and PGP Private key from JKS File and to Decrypt a pgp Encrypted Message?
问题
以下是解密PGP加密私钥消息的代码:
import java.io.*;
import java.security.*;
import java.security.cert.*;
import java.security.interfaces.*;
import java.util.*;
import org.bouncycastle.bcpg.*;
import org.bouncycastle.jcajce.provider.symmetric.*;
import org.bouncycastle.jce.provider.*;
import org.bouncycastle.openpgp.*;
import org.bouncycastle.openpgp.operator.*;
import org.bouncycastle.openpgp.operator.jcajce.*;
import org.bouncycastle.util.io.*;
public class DecClass {
public void rsaDecryptFile(InputStream in, PGPPrivateKey priK) {
try {
Security.addProvider(new BouncyCastleProvider());
in = org.bouncycastle.openpgp.PGPUtil.getDecoderStream(in);
PGPObjectFactory pgpF = new PGPObjectFactory(in);
PGPEncryptedDataList enc;
Object o = pgpF.nextObject();
if (o instanceof PGPEncryptedDataList) {
enc = (PGPEncryptedDataList) o;
} else {
enc = (PGPEncryptedDataList) pgpF.nextObject();
}
Iterator<PGPPublicKeyEncryptedData> it = enc.getEncryptedDataObjects();
PGPPrivateKey sKey = null;
PGPPublicKeyEncryptedData pbe = null;
while (sKey == null && it.hasNext()) {
pbe = it.next();
sKey = priK;
}
if (sKey == null) {
throw new IllegalArgumentException("Secret key for message not found.");
}
PublicKeyDataDecryptorFactory b = new JcePublicKeyDataDecryptorFactoryBuilder()
.setProvider("BC")
.setContentProvider("BC")
.build(sKey);
InputStream clear = pbe.getDataStream(b);
PGPObjectFactory plainFact = new PGPObjectFactory(clear, new BcKeyFingerprintCalculator());
Object message = plainFact.nextObject();
if (message instanceof PGPCompressedData) {
PGPCompressedData cData = (PGPCompressedData) message;
PGPObjectFactory pgpFact = new PGPObjectFactory(cData.getDataStream(), new BcKeyFingerprintCalculator());
message = pgpFact.nextObject();
}
if (message instanceof PGPLiteralData) {
PGPLiteralData ld = (PGPLiteralData) message;
InputStream unc = ld.getInputStream();
FileUtils.copyInputStreamToFile(unc, new File("D:\\Development_Docs\\PGP\\Bulk\\target.txt"));
} 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.");
}
if (pbe.isIntegrityProtected()) {
if (!pbe.verify()) {
throw new PGPException("Message failed integrity check");
}
}
} catch (PGPException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
请注意,这只是代码的翻译部分,其中包括了解密的主要部分以及异常处理。如果您在实际使用中遇到问题,可能需要检查其他部分的代码以查找潜在的问题。
英文:
I have the following code for decrypting a PGP encrypted Private Key Message.
KeyStore ks = KeyStore.getInstance("JKS");
File file = new file("abc.txt");
ks.load(new FileInputStream("abc.jks"), "******".toCharArray());
KeyStore.PrivateKeyEntry keyEntry =(KeyStore.PrivateKeyEntry) ks.getEntry("abcd", new KeyStore.PasswordProtection("******".toCharArray()));
PrivateKey k = keyEntry.getPrivateKey();
CertificateFactory fact = CertificateFactory.getInstance("X.509");
FileInputStream is = new FileInputStream ("ght.cer");
X509Certificate cer = (X509Certificate) fact.generateCertificate(is);
PublicKey NPCIPubKey = cer.getPublicKey();
byte[] bt = new byte[(int)file.length()];
FileInputStream fis = new FileInputStream(file);
fis.read(bt);
PGPPublicKey pk1 = new JcaPGPKeyConverter().getPGPPublicKey(PGPPublicKey.RSA_GENERAL, NPCIPubKey, new Date());
PGPPrivateKey prik = new JcaPGPKeyConverter().getPGPPrivateKey(pk1, k);
DecClass dec = new DecClass();
dec.rsaDecryptFile(fis,prik);'
Decryption Class :
public class DecClass {
public void rsaDecryptFile(InputStream in, PGPPrivateKey priK) {
try {
Security.addProvider(new BouncyCastleProvider());
in = org.bouncycastle.openpgp.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();
}
Iterator<PGPPublicKeyEncryptedData> it = enc.getEncryptedDataObjects();
PGPPrivateKey sKey = null;
PGPPublicKeyEncryptedData pbe = null;
while (sKey == null && it.hasNext()) {
pbe = it.next();
sKey = priK;
}
if (sKey == null) {
throw new IllegalArgumentException("Secret key for message not found.");
}
PublicKeyDataDecryptorFactory b = new JcePublicKeyDataDecryptorFactoryBuilder().setProvider("BC")
.setContentProvider("BC").build(sKey);
InputStream clear = pbe.getDataStream(b);
PGPObjectFactory plainFact = new PGPObjectFactory(clear,new BcKeyFingerprintCalculator());
Object message = plainFact.nextObject();
System.out.println("Secret key info 3:: " + pbe.getKeyID() + new Date());
if (message instanceof PGPCompressedData) {
PGPCompressedData cData = (PGPCompressedData) message;
PGPObjectFactory pgpFact = new PGPObjectFactory(cData.getDataStream(),new BcKeyFingerprintCalculator());
message = pgpFact.nextObject();
}
if (message instanceof PGPLiteralData) {
PGPLiteralData ld = (PGPLiteralData) message;
InputStream unc = ld.getInputStream();
int ch;
FileUtils.copyInputStreamToFile(unc, new File("D:\\Development_Docs\\PGP\\Bulk\\target.txt"));
} 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.");
}if (pbe.isIntegrityProtected()) {
if (!pbe.verify()) {
throw new PGPException("Message failed integrity check");
}
}
}catch (PGPException e) {
e.printStackTrace();
}catch (Exception e) {
e.printStackTrace();
}
}
}
But am getting null pointer exception in Iterator<PGPPublicKeyEncryptedData> it = enc.getEncryptedDataObjects();
line in DecClass
rsaDecryptFile
Method.While debugging value of PGPEncryptedDataList enc
is coming null. Am not able to trace the source of the exception. Please advise on how can i resolve this exception and get the code to work. Please find below snippet of my input encrypted message
-----BEGIN PGP MESSAGE-----
Version: BCPG v1.47
hQEMAxVcH36ac1ahAQf/UMvfmBxIEtGOcIzovhcQ8WTojB06oF8/8i5lv6iz3EEj
vIceEWSHdeCJuYSemPaiIrccOOfGFqZodg6a7IQhjG0WcuSg5F4a/Pn/7KxKqB9n
OoHwmpX0+Pbm1Y2mNAj3LN9KtK3
-----END PGP MESSAGE-----
答案1
得分: 1
我可以通过修改以下代码来解密文件。希望对您有帮助。
@SuppressWarnings({ "unchecked", "unused" })
public static void rsaDecryptFile(InputStream in, OutputStream out,
PGPPrivateKey priK) {
try {
Security.addProvider(new BouncyCastleProvider());
in = org.bouncycastle.openpgp.PGPUtil.getDecoderStream(in);
PGPObjectFactory pgpF = new PGPObjectFactory(in,new
JcaKeyFingerprintCalculator());
PGPEncryptedDataList enc;
Object o = pgpF.nextObject();
//
// 第一个对象可能是 PGP 标记数据包。
//
if (o instanceof PGPEncryptedDataList) {
enc = (PGPEncryptedDataList) o;
} else {
enc = (PGPEncryptedDataList) pgpF.nextObject();
}
//
// 查找私钥
//
PGPPrivateKey sKey = null;
PGPPublicKeyEncryptedData pbe = null;
while (sKey == null /*&& it.hasNext()*/) {
//pbe = it.next();
pbe = (PGPPublicKeyEncryptedData)enc.getEncryptedDataObjects().next();
//sKey = findSecretKey(pubK, pbe.getKeyID(), priK);
sKey = priK;
}
if (sKey == null) throw new IllegalArgumentException("未找到消息的密钥。");
PublicKeyDataDecryptorFactory b = new JcePublicKeyDataDecryptorFactoryBuilder().setProvider("BC")
.setContentProvider("BC").build(sKey);
InputStream clear = pbe.getDataStream(b);
PGPObjectFactory plainFact = new PGPObjectFactory(clear,new JcaKeyFingerprintCalculator());
Object message = plainFact.nextObject();
System.out.println("密钥信息 3:: " + pbe.getKeyID() + new Date());
if (message instanceof PGPCompressedData) {
PGPCompressedData cData = (PGPCompressedData) message;
PGPObjectFactory pgpFact = new PGPObjectFactory(cData.getDataStream(),new JcaKeyFingerprintCalculator());
message = pgpFact.nextObject();
}
if (message instanceof PGPLiteralData) {
PGPLiteralData ld = (PGPLiteralData) message;
InputStream unc = ld.getInputStream();
System.out.println("未压缩数据 " + unc.read());
int ch;
while ((ch = unc.read()) >= 0) {
out.write(ch);
}
} else if (message instanceof PGPOnePassSignatureList) {
throw new PGPException("加密的消息包含已签名的消息 - 不是字面数据。");
} else {
throw new PGPException("消息不是简单的加密文件 - 类型未知。");
}
if (pbe.isIntegrityProtected()) {
if (!pbe.verify()) {
throw new PGPException("消息完整性检查失败");
}
}
} catch (PGPException e) {
// TODO: 处理异常
e.printStackTrace();
} catch (Exception e) {
// TODO: 处理异常
e.printStackTrace();
}
}
英文:
I'm able to decrypt the file by modifing the following code.Hope it'll work for you.
@SuppressWarnings({ "unchecked", "unused" })
public static void rsaDecryptFile(InputStream in, OutputStream out,
PGPPrivateKey priK) {
try {
Security.addProvider(new BouncyCastleProvider());
in = org.bouncycastle.openpgp.PGPUtil.getDecoderStream(in);
PGPObjectFactory pgpF = new PGPObjectFactory(in,new
JcaKeyFingerprintCalculator());
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<PGPPublicKeyEncryptedData> it = enc.getEncryptedDataObjects();
PGPPrivateKey sKey = null;
PGPPublicKeyEncryptedData pbe = null;
while (sKey == null /*&& it.hasNext()*/) {
//pbe = it.next();
pbe = (PGPPublicKeyEncryptedData)enc.getEncryptedDataObjects().next();
//sKey = findSecretKey(pubK, pbe.getKeyID(), priK);
sKey = priK;
}
if (sKey == null) throw new IllegalArgumentException("Secret key for message not found.");
PublicKeyDataDecryptorFactory b = new JcePublicKeyDataDecryptorFactoryBuilder().setProvider("BC")
.setContentProvider("BC").build(sKey);
InputStream clear = pbe.getDataStream(b);
PGPObjectFactory plainFact = new PGPObjectFactory(clear,new JcaKeyFingerprintCalculator());
Object message = plainFact.nextObject();
System.out.println("Secret key info 3:: " + pbe.getKeyID() + new Date());
if (message instanceof PGPCompressedData) {
PGPCompressedData cData = (PGPCompressedData) message;
PGPObjectFactory pgpFact = new PGPObjectFactory(cData.getDataStream(),new JcaKeyFingerprintCalculator());
message = pgpFact.nextObject();
}
if (message instanceof PGPLiteralData) {
PGPLiteralData ld = (PGPLiteralData) message;
InputStream unc = ld.getInputStream();
System.out.println("Unc d " + unc.read());
int ch;
while ((ch = unc.read()) >= 0) {
out.write(ch);
}
//FileUtils.copyInputStreamToFile(unc, new File("D:\\Development_Docs\\PGP\\Bulk\\target.txt"));
} 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.");
}
if (pbe.isIntegrityProtected()) {
if (!pbe.verify()) {
throw new PGPException("Message failed integrity check");
}
}
}catch (PGPException e) {
// TODO: handle exception
e.printStackTrace();
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论