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

时间:2020-08-24 12:16:58

标签: java pgp

我有以下代码用于解密PGP加密的私钥消息。

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

解密类:

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

但是在Iterator<PGPPublicKeyEncryptedData> it = enc.getEncryptedDataObjects(); DecClass方法的rsaDecryptFile行中出现空指针异常。而PGPEncryptedDataList enc的调试值将为空。无法追踪异常的来源。请告知我如何解决此异常并使代码正常工作。请在下面的我输入的加密消息片段中找到

-----BEGIN PGP MESSAGE-----
Version: BCPG v1.47

hQEMAxVcH36ac1ahAQf/UMvfmBxIEtGOcIzovhcQ8WTojB06oF8/8i5lv6iz3EEj
vIceEWSHdeCJuYSemPaiIrccOOfGFqZodg6a7IQhjG0WcuSg5F4a/Pn/7KxKqB9n
OoHwmpX0+Pbm1Y2mNAj3LN9KtK3
-----END PGP MESSAGE-----

1 个答案:

答案 0 :(得分:0)

我可以通过修改以下代码来解密文件。希望它对您有用。

        @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();
    }
    
    
}