Bouncy Castle 从公钥加密会话数据包中提取 PGP 会话密钥
Posted
技术标签:
【中文标题】Bouncy Castle 从公钥加密会话数据包中提取 PGP 会话密钥【英文标题】:Bouncy Castle Extract PGP Session Key from Public-Key Encrypted Session Packet 【发布时间】:2018-03-16 07:46:16 【问题描述】:我有一个 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 加密值 m**e mod n 的多精度整数 (MPI)。
上述公式中的“m”值是从会话密钥导出的 如下。首先,会话密钥以一个八位字节为前缀 指定对称加密的算法标识符 用于加密以下对称加密数据的算法 包。然后附加一个两个八位字节的校验和,它等于 前一个会话密钥八位字节的总和,不包括算法 标识符,以 65536 为模。然后按照中所述对这个值进行编码 [RFC3447] 第 7.2.1 节中的 PKCS#1 块编码 EME-PKCS1-v1_5 到 形成上述公式中使用的“m”值。请参阅第 13.1 节 本文档是关于 OpenPGP 使用 PKCS#1 的说明。
任何关于如何解决这个难题的建议将不胜感激,谢谢!
【问题讨论】:
您是否拆分了数据包的前几个标头字节(或确保 Bouncy Castle 已经这样做了)?pgpdump -pi
还应该将会话密钥打印为整数值,您应该能够将 Java 代码的结果与这个进行比较。
@JensErat 事实证明,Bouncy Castle 以 MPI 格式输出会话密钥,前两个字节代表总边。剥离这些后,我能够解密会话密钥,但仍然无法从解码的原始字节中获取任何明智的密钥
【参考方案1】:
原来,Bouncy Castle 使用 MPI 格式导出加密的会话密钥,其中前 2 个字节是长度。这解决了我无法解密会话密钥的原始问题,因为它是 258 字节而不是 256 字节。
尽管仍然无法使用 --override-session-key 和现在解密的会话密钥的原始字节解密文件,但我将这个问题标记为已回答。
【讨论】:
您好,希望您能就设置充气城堡以连接我的 C 客户端提供建议。我正在尝试设置有弹性的反向移植 gnutls 应用程序(mandos-server)。任何帮助将不胜感激以上是关于Bouncy Castle 从公钥加密会话数据包中提取 PGP 会话密钥的主要内容,如果未能解决你的问题,请参考以下文章
在没有 Bouncy Castle 的情况下,如何在 java 中从私有(ecdsa)生成公钥?
如何使用Bouncy Castle Crypto API来加密和解密数据
使用 Bouncy Castle 将 RSA 公钥转换为 RFC 4716 公钥
仅使用 Bouncy Castle 读取 PEM RSA 公钥