如何从JKS文件中提取PGP公钥和PGP私钥,并解密PGP加密消息?

huangapple go评论89阅读模式
英文:

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(&quot;JKS&quot;);
File file = new file(&quot;abc.txt&quot;);
ks.load(new FileInputStream(&quot;abc.jks&quot;), &quot;******&quot;.toCharArray());
KeyStore.PrivateKeyEntry keyEntry =(KeyStore.PrivateKeyEntry) ks.getEntry(&quot;abcd&quot;, new KeyStore.PasswordProtection(&quot;******&quot;.toCharArray()));
PrivateKey k = keyEntry.getPrivateKey();
CertificateFactory fact = CertificateFactory.getInstance(&quot;X.509&quot;);
FileInputStream is = new FileInputStream (&quot;ght.cer&quot;);
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);&#39;

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&lt;PGPPublicKeyEncryptedData&gt; it = enc.getEncryptedDataObjects();
PGPPrivateKey sKey = null;
PGPPublicKeyEncryptedData pbe = null;
while (sKey == null &amp;&amp; it.hasNext()) {
pbe = it.next();
sKey = priK;
}
if (sKey == null) {
throw new IllegalArgumentException(&quot;Secret key for message not found.&quot;);
}
PublicKeyDataDecryptorFactory b = new JcePublicKeyDataDecryptorFactoryBuilder().setProvider(&quot;BC&quot;)
.setContentProvider(&quot;BC&quot;).build(sKey);
InputStream clear = pbe.getDataStream(b);
PGPObjectFactory plainFact = new PGPObjectFactory(clear,new BcKeyFingerprintCalculator());
Object message = plainFact.nextObject();
System.out.println(&quot;Secret key info 3:: &quot; + 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(&quot;D:\\Development_Docs\\PGP\\Bulk\\target.txt&quot;));
} else if (message instanceof PGPOnePassSignatureList) {
throw new PGPException(&quot;Encrypted message contains a signed message - not literal data.&quot;);
} else {
throw new PGPException(&quot;Message is not a simple encrypted file - type unknown.&quot;);
}if (pbe.isIntegrityProtected()) {
if (!pbe.verify()) {
throw new PGPException(&quot;Message failed integrity check&quot;);
}
}			
}catch (PGPException e) {
e.printStackTrace();
}catch (Exception e) {
e.printStackTrace();
}	
}
}

But am getting null pointer exception in Iterator&lt;PGPPublicKeyEncryptedData&gt; 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({ &quot;unchecked&quot;, &quot;unused&quot; })
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&lt;PGPPublicKeyEncryptedData&gt; it = enc.getEncryptedDataObjects();
PGPPrivateKey sKey = null;
PGPPublicKeyEncryptedData pbe = null;
while (sKey == null /*&amp;&amp; it.hasNext()*/) {
//pbe = it.next();
pbe = (PGPPublicKeyEncryptedData)enc.getEncryptedDataObjects().next();
//sKey = findSecretKey(pubK, pbe.getKeyID(), priK);
sKey = priK;
}
if (sKey == null) throw new IllegalArgumentException(&quot;Secret key for message not found.&quot;);
PublicKeyDataDecryptorFactory b = new JcePublicKeyDataDecryptorFactoryBuilder().setProvider(&quot;BC&quot;)
.setContentProvider(&quot;BC&quot;).build(sKey);
InputStream clear = pbe.getDataStream(b);
PGPObjectFactory plainFact = new PGPObjectFactory(clear,new JcaKeyFingerprintCalculator());
Object message = plainFact.nextObject();
System.out.println(&quot;Secret key info 3:: &quot; + 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(&quot;Unc d &quot; + unc.read());
int ch;
while ((ch = unc.read()) &gt;= 0) { 
out.write(ch); 
}
//FileUtils.copyInputStreamToFile(unc, new File(&quot;D:\\Development_Docs\\PGP\\Bulk\\target.txt&quot;));
} else if (message instanceof PGPOnePassSignatureList) {
throw new PGPException(&quot;Encrypted message contains a signed message - not literal data.&quot;);
} else {
throw new PGPException(&quot;Message is not a simple encrypted file - type unknown.&quot;);
}
if (pbe.isIntegrityProtected()) {
if (!pbe.verify()) {
throw new PGPException(&quot;Message failed integrity check&quot;);
}
}
}catch (PGPException e) {
// TODO: handle exception
e.printStackTrace();
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}

huangapple
  • 本文由 发表于 2020年8月24日 20:16:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/63560896.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定