我有一个使用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 sion-key解密原始文件。
有人知道这个设置会出什么问题吗?
我认为(至少)有两件事应该出错。
(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
而不是-red
。
注意RSA加密的密钥块'm',按照第5.1秒由1个八位字节对称算法、实际密钥和2个八位字节校验和组成;前两个由冒号分隔,第三个不包含在GPG的会话密钥中。