解密 PgP 加密文件

问题描述 投票:0回答:0

我目前正在使用 PgPEncryptionService 并成功地使用我的公钥加密文件。我面临的问题是解密。

我目前在为我的解密方法运行测试用例时收到此错误。

[main] INFO com.rxbenefits.service.impl.PGPEncryptionService - Secret key algorithm: 9

org.bouncycastle.openpgp.PGPException: unknown hash algorithm: 8

    at org.bouncycastle.openpgp.PGPUtil.getS2kDigestName(Unknown Source)
    at org.bouncycastle.openpgp.PGPUtil.makeKeyFromPassPhrase(Unknown Source)
    at org.bouncycastle.openpgp.PGPSecretKey.extractKeyData(Unknown Source)
    at org.bouncycastle.openpgp.PGPSecretKey.extractPrivateKey(Unknown Source)
    at org.bouncycastle.openpgp.PGPSecretKey.extractPrivateKey(Unknown Source)
    at com.rxbenefits.service.impl.PGPEncryptionService.findSecretKey(PGPEncryptionService.java:102)
    at com.rxbenefits.service.impl.PGPEncryptionService.decryptFile(PGPEncryptionService.java:132)
    at com.rxbenefits.service.impl.PGPEncryptionServiceTest.testFileEncryption(PGPEncryptionServiceTest.java:55)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.mockito.internal.runners.DefaultInternalRunner$1$1.evaluate(DefaultInternalRunner.java:54)
    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)

在调试中运行时,我可以看到值通过正常......我在算法 9 的调试器中唯一能找到的就是下图所示的

enter image description here

总之。我不知道自己做错了什么。我自己生成了这些密钥,并且能够使用 pub 密钥进行加密……但由于某种原因,解密让我很头疼。以下是我用来解密的两种方法。

这是解密方法

    /**
     * decrypt the passed in message stream
     */
    @SuppressWarnings("unchecked")
    public static void decryptFile(InputStream in, OutputStream out, InputStream keyIn, char[] passwd) throws Exception
    {
        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();
        }
        // find the secret key
        Iterator<PGPPublicKeyEncryptedData> it = enc.getEncryptedDataObjects();
        PGPPrivateKey sKey = null;
        PGPPublicKeyEncryptedData pbe = null;
        while (sKey == null && it.hasNext())
        {
            pbe = it.next();
            sKey = findSecretKey(keyIn, pbe.getKeyID(), passwd);
        }
        if (sKey == null)
        {
            throw new IllegalArgumentException("Secret key for message not found.");
        }
        InputStream clear = pbe.getDataStream(sKey, "BC");
        PGPObjectFactory plainFact = new PGPObjectFactory(clear);
        Object message = plainFact.nextObject();
        PGPObjectFactory pgpFact = null;
        if (message instanceof PGPCompressedData)
        {
            PGPCompressedData cData = (PGPCompressedData) message;
            pgpFact = new PGPObjectFactory(cData.getDataStream());
            message = pgpFact.nextObject();
        }
        if (message instanceof PGPLiteralData)
        {
            PGPLiteralData ld = (PGPLiteralData) message;
            InputStream unc = ld.getInputStream();
            int ch;
            while ((ch = unc.read()) >= 0)
            {
                out.write(ch);
            }
        }
        else if (message instanceof PGPOnePassSignatureList)
        {
            PGPOnePassSignatureList p1 = (PGPOnePassSignatureList) message;

            PGPOnePassSignature ops = p1.get(0);

            PGPLiteralData ld = (PGPLiteralData) pgpFact.nextObject();

            InputStream unc = ld.getInputStream();
            int ch;
            while ((ch = unc.read()) >= 0)
            {
                out.write(ch);
            }
        }
        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");
            }
        }
    }

这是用来获取密钥的方法

private static PGPPrivateKey findSecretKey(InputStream keyIn, long keyID, char[] pass) throws IOException, PGPException, NoSuchProviderException {
        PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(org.bouncycastle.openpgp.PGPUtil.getDecoderStream(keyIn));
        PGPSecretKey pgpSecKey = pgpSec.getSecretKey(keyID);

        if (pgpSecKey == null) {
            return null;
        }

        log.info("Secret key algorithm: " + pgpSecKey.getKeyEncryptionAlgorithm());

        return pgpSecKey.extractPrivateKey(pass, "BC");
    }

这是我对以上内容的单元测试

       @Test
        public void testFileEncryption() throws Exception {
            // create unencrypted file
        String tempPath = "temp";
        FileRepo fileRepo = new FileRepo();
        fileRepo.setEncryptionKeyNo(123L);

        // Create the unencrypted file
        File unencryptedFile = new File("unencrypted.txt");
        try (PrintWriter writer = new PrintWriter(unencryptedFile)) {
            writer.println("Hello, world!");
        }

        // Encrypt the file
        File encryptedFile = new File(tempPath + unencryptedFile.getName() + ".pgp");
        File encryptedResult = new File("encrypted.txt");
        try (OutputStream out = new DataOutputStream(new FileOutputStream(encryptedFile));
             FileInputStream publicKeyStream = new FileInputStream(publicKey)) {
            encryptFile(out, unencryptedFile.getPath(), readPublicKey(publicKeyStream), false, true);
            try (InputStream in = new FileInputStream(encryptedFile);
                 OutputStream outResult = new FileOutputStream(encryptedResult);
                 FileInputStream privateKeyStream = new FileInputStream(secretKey)) {
                // Decrypt the encrypted file
                decryptFile(in, outResult, privateKeyStream, passPhrase);
            }
        }

        // Check that the decrypted file matches the original unencrypted file
        try (BufferedReader reader1 = new BufferedReader(new FileReader(unencryptedFile));
             BufferedReader reader2 = new BufferedReader(new FileReader(encryptedResult))) {
            String line1 = reader1.readLine();
            String line2 = reader2.readLine();
            while (line1 != null && line2 != null) {
                assertEquals(line1, line2);
                line1 = reader1.readLine();
                line2 = reader2.readLine();
            }
            assertNull(line1);
            assertNull(line2);
        }

        // Clean up the files
        unencryptedFile.delete();
        encryptedFile.delete();
        encryptedResult.delete();
    }

findSecretKey 方法是我收到错误的方法。特别是当它返回 pgpSecKey.extractPrivateKey 时。

我认为是问题所在:

密码错误。 (事实并非如此。我创建了 4 个不同的密钥对,密码为 12345,但均无效)

更改加密时使用的算法。 (现在使用 AES_256,错误仍然存在)

java public-key-encryption public-key pgp secret-key
© www.soinside.com 2019 - 2024. All rights reserved.