如何使用WinCrypt和C ++导入PEM格式的私钥?

时间:2011-12-07 09:15:29

标签: c++ windows cryptography cryptoapi pem

我正在尝试在C ++中使用WinCrypt API

我的应用程序需要加密,解密,签名和验证文件,一旦我有正确的密钥,我就知道如何做到这一点。但我的问题实际上是,这与生成这些密钥的应用程序不同。

我所拥有的是PEM格式的文​​件中的公钥和私钥:

-----BEGIN RSA PRIVATE KEY-----
[Base64 encoded]
-----END RSA PRIVATE KEY-----

并且:

-----BEGIN RSA PUBLIC KEY-----
[Base64 encoded]
-----END RSA PUBLIC KEY-----

经过一些研究,我找到了如何使用以下方法导入公钥:herehere

  • CreateFile & ReadFile 以阅读文件内容
  • CryptStringToBinary CRYPT_STRING_BASE64HEADER 可将PEM格式转换为DER格式(删除页眉和页脚以及从base64解码)
  • CryptDecodeObjectEx X509_PUBLIC_KEY_INFO
  • CryptImportPublicKeyInfo ,导入密钥

但是现在,我的问题是用私钥做同样的事情。 任何帮助真的很感激:) 谢谢。

2 个答案:

答案 0 :(得分:8)

可以使用 CryptDecodeObjectEx PKCS_RSA_PRIVATE_KEY 将PEM私钥导入CAPI,然后调用 CryptImportKey

我编写了一个示例,演示了如何使用PEM编码的RSA私钥来使用CAPI对数据进行签名。以下是指向它的链接:http://www.idrix.fr/Root/Samples/capi_pem.cpp

我希望这会有所帮助。

答案 1 :(得分:0)

我遇到了一个PEM格式的加密私钥问题。这是我解密并导入它的过程:

  1. 使用override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { if(requestCode == RESOLVE_PHONE_NUMBER_HINT){ if (resultCode == RESULT_OK) { var credential : Credential? = data?.getParcelableExtra(Credential.EXTRA_KEY) credential?.apply { processPhoneNumber(id) } } } CryptStringToBinaryA来解码PEM
  2. 使用CRYPT_STRING_BASE64HEADERCryptDecodeObjectPKCS_7_ASN_ENCODING解码为ASN.1数据
    • 这会产生一些有关如何加密密钥和实际加密数据的信息。就我而言,密钥来自OpenSSL,加密由RFC 8018, Appendix A.4描述。
    • 我不得不手动编写一些代码来解析此结构,因为PKCS_ENCRYPTED_PRIVATE_KEY_INFO本身不支持该结构。您可以找到该代码here
  3. 一旦您获得了私钥的加密以及有关如何导出对称密钥以及使用哪种算法对其进行解密的信息(在我的情况下为PBKDF2和AES-256-CBC):
    1. 使用CryptDecodeObject从密码中获取加密密钥
    2. 使用BCryptDeriveKeyPBKDF2使用从密码派生的对称密钥解密私钥。
  4. BCryptDecryptCryptDecodeObjectPKCS_7_ASN_ENCODING一起使用
  5. 在上一步中生成的PKCS_PRIVATE_KEY_INFO数据成员上,将CryptDecodeObjectPKCS_7_ASN_ENCODINGPKCS_RSA_PRIVATE_KEY一起使用。

最后一步的输出是RSA Private Key BLOB。可以使用PrivateKeyBCryptImportKeyPair导入。同样,可以在here中找到展示所有这些内容的代码。