CryptBinaryToString没有输出预期的公钥

时间:2019-05-14 19:38:44

标签: windows winapi base64 certificate cryptoapi

我正在尝试使用Windows CryptoAPI函数输出导入的RSA公钥的原始base64形式。使用带有CRYPT_STRING_BASE64HEADER标志的CryptBinaryToString,输出标头读取“ BEGIN CERTIFICATE”,而不是预期的“ BEGIN PUBLIC KEY”。

(编辑:我没有突出问题的这一部分) 此外,生成的公共密钥似乎与原始密钥不同。

如果我要导出输出然后重新导入,这会成为问题吗?如果是这样,我在做什么错了?

这是导入公钥的方式。

公钥以以下PEM格式存储在pubkey.pem文件中:

-----BEGIN PUBLIC KEY-----
[REDACTED]
-----END PUBLIC KEY-----

使用CreateFile / ReadFile将文件读入缓冲区。 使用CryptStringToBinaryA将PEM转换为二进制。 使用CryptDecodeObjectEx将二进制解码为X509_PUBLIC_KEY_INFO。 PubKeyInfo结构被解码为RSA_CSP_PUBLICKEYBLOB(与上述功能相同)。

这部分工作正常(可以导入密钥并使用CryptImportKey,CryptEncrypt等加密数据)。

这是我拼凑的代码,试图将原始Blob恢复为base64 PEM格式。我已经删除了大多数错误检查程序,以免造成麻烦。

pbTmp和cbTmp是分别保存输出和大小的临时缓冲区。 pBinaryKey是原始公钥blob(从较早版本导入) pBuffer是输出缓冲区(假定为正确大小) ulDataLen是输出缓冲区的大小

CryptEncodeObjectEx(X509_ASN_ENCODING, RSA_CSP_PUBLICKEYBLOB, pBinaryKey, 0, NULL, NULL, &cbTmp)
pbTmp = malloc(cbTmp);
CryptEncodeObjectEx(X509_ASN_ENCODING, RSA_CSP_PUBLICKEYBLOB, pBinaryKey, 0, NULL, pbTmp, &cbTmp)
CryptBinaryToStringA(pbTmp, cbTmp, CRYPT_STRING_BASE64HEADER, NULL, &ulDataLen)
CryptBinaryToStringA(pbTmp, cbTmp, CRYPT_STRING_BASE64HEADER, pBuffer, &ulDataLen)

最终的缓冲区以以下形式结束:

-----BEGIN CERTIFICATE-----
[REDACTED; DIFFERENT FROM ORIGINAL PUBLIC KEY]
-----END CERTIFICATE-----

1 个答案:

答案 0 :(得分:0)

根据document

  

CRYPT_STRING_BASE64HEADER(0x00000000):Base64,具有证书   开头和结尾标头。

期望的标题是“ BEGIN CERTIFICATE”。并且“ BEGIN PUBLIC KEY”没有其他标志参数支持。就像@Jonathan Potter所说的那样,您始终可以使用CRYPT_STRING_BASE64标志来进行编码而不使用标头,然后自己添加正确的标头。

另外,这是关于answer的另一件事,内容是有关使用openssl从CERTIFICATE获取PUBILC的信息。