我有一个生成的 RSA 密钥对,存储为 PRIVATEKEYBLOB 和 PUBLICKEYBLOB,并且我需要能够将这些密钥转换为 DER 或 PEM 格式,以便我可以在 PHP 或 Python 中使用它。我发现我可以使用 CryptEncodeObject 函数将 PRIVATEKEYBLOB 转换为 DER。为了做到这一点,我需要使用 PKCS_RSA_PRIVATE_KEY 编码标志。但我找不到任何关于如何将 PUBLICKEYBLOB 转换为 DER 的线索。
这是我的 PRIVATE KEY BLOB 转换代码:
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 获得的输出连接起来,一切都可以正常工作。但不确定该标头是否始终相同。