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

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

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:

确定