我有一个工具,它采用 RSA 公钥(例如 OpenSSL PEM 格式密钥),将消息加密为该公钥,然后返回加密的消息。我将收到一个 PGP 公钥,需要将其传递给接受 RSA 公钥的工具,然后将加密数据返回给发送 PGP 密钥的人,以便他们可以使用 PGP 对其进行解密。
我发现的最接近的问题是“如何使用 openssl 命令执行 PGP 加密和解密方法”,虽然这不是我想要的,但它确实提供了部分解决方案。但是,我正在寻找更多内容,特别是如何在两种格式之间进行转换。
如何获取 PGP 密钥,从中提取公共 RSA 密钥,将其转换为 PEM 格式,然后获取加密数据并将其放回 PGP 可理解的格式?
用 OpenSSL 转换密钥并不容易;您必须自己编写所有 PGP 解析代码,请参阅RFC 4880。将 n 和 e 值作为字节数组后,您可以将它们放入 bignums 中,然后放入 RSA 结构中,然后调用
PEM_write[_bio]_RSA_PUBKEY
. 就我个人而言,我会使用 BouncyCastle 在 Java 中执行此操作,它直接支持 jar 中的 PGP 密钥和数据以及bcpg
jar 中的 OpenSSL 密钥(和一些数据)bcpkix
。转换数据可能是不可能的。首先,“一条消息”不太可能简单地用 RSA 加密——RSA 仅适用于有限大小的数据,目前大约 200 字节,这通常不足以满足人们想要的数据(除了 'twits' )。在实践中,系统和应用程序几乎总是使用“混合”加密——数据使用“对称”(经典密钥)算法加密,例如带有 nonce 密钥的 AES,而 nonce 密钥使用“非对称”加密'(公钥)RSA 算法。有几种不同的方式进行 RSA 加密,以及数十到数百种不同的方式(主要是“模式”)进行对称加密。您需要确切了解“工具”正在执行哪种加密。
对于(通常的)to-recipient-pubkey 情况,PGP 使用最初的 PKCS1 'block type 02' 加密,现在重新命名为 RSAES-PKCS1-v1_5,并结合了几种对称算法(一些常见但有些不是)中的一种其他人根本不使用的 CFB 模式的变体(本世纪很少有其他东西使用任何类型的 CFB)。PGP 接收者可能只能接受对称算法的一个子集,如果是这样,这在 PGP 密钥块中表示,发送者应该读取并尊重它,但 OpenSSL 使用的公钥格式是X.509/PKIX 中的 SubjectPublicKeyInfo 结构不能表示此信息。(X.509/PKIX证书,OpenSSL 也支持和大多数精心设计的 OpenSSL 软件使用,可以表示此信息,但与 PGP 的形式非常不同。)
此外,PGP 的 CFB 变体是非身份验证的。早在 1990 年,人们并没有意识到这是一个漏洞,但现在它是,所以许多收件人需要或至少更喜欢使用 PGP 选项进行身份验证,这就是其他人现在所说的消息身份验证代码,但 PGP 称为修改检测代码。PGP 的 MDC 方案与其他任何东西使用的任何 MAC 方案都不相同。
因此,简而言之,除非“工具”被设计为进行 PGP 加密,否则它的输出不能“转换”为 PGP,除非对其进行解密和重新加密。如果它是由一个理智的人设计来进行 PGP 加密的,它会接受 PGP 公钥。但是,由于该工具无法确定上述“SPKI”公钥是否确实属于预期的接收者,因此您可以生成自己的密钥对,为工具提供您的公钥,接收使用您的密钥加密的数据并对其进行解密,然后然后使用实际的接收者密钥和匹配该密钥的算法(和 MDC 选项)以 PGP 兼容格式重新加密。