如何解密PGP加密文件(由两个PGP密钥加密.Key1具有公钥,私钥.Key2只有公钥)通过JAVA API

时间:2017-03-26 10:22:31

标签: java pgp openpgp

我在PGP桌面上有两个PGP密钥。

  • Key1 - 在我的PGP桌面上创建。其中包含公钥和私钥
  • Key2 - 由我的客户创建并仅与我们共享公钥。我只在我的PGP桌面上添加了key2公钥。

现在我使用以上两个密钥加密文件。我可以使用PGP Desktop成功解密文件。

但我无法使用Java API解密文件。

public static void decryptFile(File input, File key, char[] passwd, File destDir) throws Exception {
        File destFile = null;
        InputStream keyIn = new FileInputStream(key);
        Security.addProvider(new BouncyCastleProvider());

        InputStream is = new FileInputStream(input);
        InputStream in = org.bouncycastle.openpgp.PGPUtil.getDecoderStream(is);
        try {

            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> encDataObjects = enc.getEncryptedDataObjects();
            PGPPublicKeyEncryptedData encryptedData = null;
            List<Long> keyIds = new LinkedList<Long>();
            while (encDataObjects.hasNext()) {
                encryptedData = (PGPPublicKeyEncryptedData) encDataObjects.next();
                long decipheringKeyID = encryptedData.getKeyID();
                System.out.println("****** Key ID ****** "+decipheringKeyID);
                keyIds.add(decipheringKeyID);
            }
            PGPSecretKey decipheringKey = readSecretKey(keyIn, keyIds);
            if (decipheringKey == null) {
                throw new IllegalArgumentException("Secret key for message not found.");
            }
            PGPPrivateKey decryptionKey = findPrivateKey(decipheringKey, passwd);
            if (decryptionKey == null) {
                throw new IllegalArgumentException("Private key for message not found.");
            }

            PublicKeyDataDecryptorFactory dataDecryptorFactory = new BcPublicKeyDataDecryptorFactory(decryptionKey);
            InputStream clear = encryptedData.getDataStream(dataDecryptorFactory);

            PGPObjectFactory plainFact = new PGPObjectFactory(clear);

            Object message = plainFact.nextObject();

            if (message instanceof PGPCompressedData) {
                PGPCompressedData cData = (PGPCompressedData) message;
                PGPObjectFactory pgpFact = new PGPObjectFactory(cData.getDataStream());
                message = pgpFact.nextObject();
            }
            if (message instanceof PGPOnePassSignatureList) {
                // TODO: Verify file
                message = plainFact.nextObject();
            }
            if (message instanceof PGPLiteralData) {
                PGPLiteralData ld = (PGPLiteralData) message;

                InputStream unc = ld.getInputStream();
                int ch;
                ByteArrayOutputStream out = new ByteArrayOutputStream();

                if(ld.getFileName().toString() == null || ld.getFileName().toString().equals(""))
                {
                    String[] fname = input.getAbsolutePath().split("\\\\");
                    destFile = new File(destDir,fname[fname.length-1].replace(".pgp", ""));
                }
                else
                {
                     destFile = new File(destDir, ld.getFileName());
                }
                FileOutputStream fos = new FileOutputStream(destFile);
                while ((ch = unc.read()) >= 0) {
                    out.write(ch);
                }
                byte[] returnBytes = out.toByteArray();
                out.close();
                fos.write(returnBytes);
                fos.close();
            } else {
                throw new PGPException("Message is not a simple encrypted file - type unknown.");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new Exception(ex.getMessage());
        } finally {
            if (keyIn != null) {
                keyIn.close();
            }
            if (in != null) {
                in.close();
            }
            if (is != null) {
                is.close();
            }
        }
    }

我收到以下错误

org.bouncycastle.openpgp.PGPException: exception encrypting session info: unknown block type
    at org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory.recoverSessionData(Unknown Source)
    at org.bouncycastle.openpgp.PGPPublicKeyEncryptedData.getDataStream(Unknown Source)
    at com.pgp.util.PGPUtils.decryptFile(PGPUtils.java:312)
    at com.pgp.util.PGPUtils.main(PGPUtils.java:576)
Caused by: org.bouncycastle.crypto.InvalidCipherTextException: unknown block type
    at org.bouncycastle.crypto.encodings.PKCS1Encoding.decodeBlock(Unknown Source)
    at org.bouncycastle.crypto.encodings.PKCS1Encoding.processBlock(Unknown Source)
    at org.bouncycastle.crypto.BufferedAsymmetricBlockCipher.doFinal(Unknown Source)
    ... 4 more
Exception in thread "main" java.lang.Exception: exception encrypting session info: unknown block type
    at com.pgp.util.PGPUtils.decryptFile(PGPUtils.java:373)
    at com.pgp.util.PGPUtils.main(PGPUtils.java:576)

0 个答案:

没有答案