解密OpenPGP会话密钥

时间:2017-10-05 22:27:00

标签: cryptography rsa bouncycastle gnupg openpgp

我有一个使用GPG加密的文件,我想从中提取会话密钥,因此我可以单独解密会话密钥。我使用Bouncy Castle使用以下代码提取会话密钥:

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_dec.bin -inkey private.pem -raw

我希望原始输出现在是解密的会话密钥,但是我无法使用它来使用--override-session-key解密原始文件。

有没有人知道这个设置可能出现什么问题?

1 个答案:

答案 0 :(得分:0)

我看到应该出错的两件事(至少)。

(0)您显然假设使用的密钥(和算法)是RSA,这不是PGP和GPG使用的唯一加密算法。

(1)PublicKeyEncSessionPacket.getEncSessionKey()的元素是MPInteger.getEncoded()的结果,即来自rfc4880 sec 3.2的MPI编码,其是两个八位位长,后跟实际值八位字节。写入时该值对于RSA解密而言应该太大而rsautl -decrypt应该给出错误,至少假设您使用的是正确的密钥。

(2)PGP的RSA加密使用PKCS1-v1_5(02型)填充。纠正(1)后,您需要使用默认的-pkcs而不是-raw

这些改变对我有用。注意RSA加密的密钥块'm',按照sec 5.1由1个八位位组对称算法,实际密钥和2个八位字节校验和组成;前两个用冒号分隔,第三个不包含在GPG的会话密钥中。