Bouncy Castle从公钥加密会话包中提取PGP会话密钥

时间:2017-10-04 19:42:24

标签: openssl cryptography bouncycastle gnupg openpgp

我有一个PGP Public-Key Encrypted Session Packet,我想从中提取会话密钥,以便我可以单独解密会话密钥。我正在使用BouncyCastle库并正在提取会话密钥,如下所示:

private static void outputSessionKey(String path) throws FileNotFoundException, IOException {
    BCPGInputStream input = new BCPGInputStream(PGPUtil.getDecoderStream(new FileInputStream(path)));
    Packet packet;
    while((packet = input.readPacket()) != null) {
        if (packet instanceof PublicKeyEncSessionPacket) {
            PublicKeyEncSessionPacket encPacket = (PublicKeyEncSessionPacket) packet;
            byte[] encKey = encPacket.getEncSessionKey()[0];
            FileOutputStream output = new FileOutputStream("session_key_enc.bin");
            output.write(encKey);
            output.close();
        }
    }

    input.close();
}

我当时希望能够使用openssl解密会话密钥:

openssl rsautl -decrypt -in session_key_enc.bin -out session_key_decoded.bin -inkey private.pem

其中 session_key_enc.bin 是二进制格式的加密会话密钥, private.pem 是用于加密GPG中数据的公钥的相应私钥。在加密我的数据之前,我将RSA密钥对的公钥部分转换为PGP格式的密钥并将其导入GPG。

当我运行OpenSSL命令时,我收到此错误:

RSA operation error
140624851898072:error:0406506C:rsa routines:RSA_EAY_PRIVATE_DECRYPT:data greater than mod len:rsa_eay.c:518:

检查 session_key_enc.bin 后,我发现文件是258个字节。考虑到我使用2048位RSA密钥并且规范表明加密的会话密钥由n修改,这似乎不太可能。

  

RSA加密的算法特定字段        - RSA加密值的多精度整数(MPI)m ** e mod n。

     

价值" m"在上面的公式中派生自会话密钥     如下。首先,会话密钥以一个八位字节为前缀     用于指定对称加密的算法标识符     用于加密以下对称加密数据的算法     包。然后附加一个两个八位字节的校验和,它等于     前一个会话密钥八位字节的总和,不包括算法     标识符,模数65536.然后按照中所述对该值进行编码     PKCS#1块编码[RFC3447]的第7.2.1节中的EME-PKCS1-v1_5     形成" m"在上面的公式中使用的值。见第13.1节     本文档提供了有关OpenPGP使用PKCS#1的说明。

非常感谢任何关于如何解决这个难题的建议,谢谢!

1 个答案:

答案 0 :(得分:0)

原来Bouncy Castle使用MPI格式导出加密的会话密钥,其中前2个字节是长度。这解决了我无法解密会话密钥的原始问题,因为它是258字节而不是256字节。

我正在回答这个问题,尽管仍然无法使用--override-session-key和现在解密的会话密钥的原始字节解密文件。