我有一个生成的 RSA 密钥对存储为 PRIVATEKEYBLOB 和 PUBLICKEYBLOB,我需要能够将这些密钥转换为 DER 或 PEM 格式,以便我可以在 PHP 或 Python 中使用它。我发现我可以使用 CryptEncodeObject 函数将我的 PRIVATEKEYBLOB 转换为 DER。为此,我需要使用 PKCS_RSA_PRIVATE_KEY 编码标志。但我找不到任何关于如何将 PUBLICKEYBLOB 转换为 DER 的线索。
这是我的 PRIVATEKEYBLOB 转换代码:
LPCSTR type = PKCS_RSA_PRIVATE_KEY;
DWORD encd = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
DWORD dlen = 0;
if(!CryptEncodeObject(encd, type, key, null, &dlen))
{ LOG_ERROR(); return false; }
// Buffer allocation (der variable)
if(!CryptEncodeObject(encd, type, key, der, &dlen))
{ LOG_ERROR(); return false; }
我通过将它们与 openssl 工具的输出进行比较来测试我的密钥:
openssl rsa -pubin -inform MS\ PUBLICKEYBLOB -in pub.ms -outform DER -out pub.der
openssl rsa -inform MS\ PRIVATEKEYBLOB -in pri.ms -outform DER -out pri.der
补充:我用 X509_ASN_ENCODING 尝试了 RSA_CSP_PUBLICKEYBLOB,但结果与 openssl 工具的输出不同,并且密钥导入失败。openssl 导出的 DER 长了 25 个字节,两个键中只有前 3 个字节相等。这是关键比较的图片:
如果我们仔细看这张图,我们可以看到 openssl 的密钥版本在第 3 个字节之后有某种额外的 24 字节头。到目前为止还没有弄清楚它是什么,但是如果我将这个硬编码的标头与我从 CryptEncodeObject 获得的输出与 RSA_CSP_PUBLICKEYBLOB 连接起来,它一切正常。不确定该标题是否始终相同。