Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows CryptBinaryToString未输出预期的公钥_Windows_Winapi_Base64_Certificate_Cryptoapi - Fatal编程技术网

Windows CryptBinaryToString未输出预期的公钥

Windows CryptBinaryToString未输出预期的公钥,windows,winapi,base64,certificate,cryptoapi,Windows,Winapi,Base64,Certificate,Cryptoapi,我正在尝试使用Windows CryptoAPI函数输出导入的RSA公钥的原始base64形式。使用带有CRYPT_STRING_Base64头标志的CryptBinaryToString,输出头将读取“BEGIN CERTIFICATE”,而不是预期的“BEGIN PUBLIC KEY” (编辑:我没有强调我问题的这一部分) 此外,生成的公钥似乎与原始公钥不同 如果我导出输出并重新导入它,这会有问题吗?如果是,我做错了什么 下面是如何导入公钥的 公钥以以下pem格式存储在文件pubkey.pe

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

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

如果我导出输出并重新导入它,这会有问题吗?如果是,我做错了什么

下面是如何导入公钥的

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

-----BEGIN PUBLIC KEY-----
[REDACTED]
-----END PUBLIC KEY-----
使用CreateFile/ReadFile将文件读入缓冲区。 使用CryptStringToBinaryA将PEM转换为二进制。 使用CryptDecodeObjectEx将二进制文件解码为X509_公钥_密钥_信息。 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-----
根据报告:

CRYPT_STRING_Base64头(0x00000000):Base64,带有证书 开头和结尾的标题

预期的标题是“开始证书”。并且没有其他标志参数支持“BEGIN PUBLIC KEY”。正如@Jonathan Potter所说,您可以始终使用
CRYPT\u STRING\u BASE64
标志来编码而不使用头,然后自己添加正确的头


另外,还有一个关于使用openssl从证书获取PUBILC的问题。

看起来API只支持
证书
证书请求
X509 CRL
的头。这是否重要取决于将要解释数据的程序。您可以始终使用
CRYPT\u STRING\u BASE64
标志进行无头编码,然后自己添加正确的头。好的,这可以处理头问题…但生成的公钥仍然与原始公钥不同。我的私钥(使用CryptEncodeObject的
PKCS\u RSA\u private\u key
标志)不会出现此问题。似乎这个问题在这里没有得到解决@alpha1693,二进制文件使用CryptoDecodeObjectEx解码为X509_PUBLIC_KEY_INFO。PubKeyInfo结构被解码为RSA_CSP_PUBLICKEYBLOB(与上述功能相同):
pvStructInfo
参数是指向结构的指针。因此,
CryptEncodeObjectEx
的类型标志也应该是
X509\u PUBLIC\u KEY\u INFO