我正在使用 Microsoft CNG Cryptography API 并尝试创建自签名证书。
我们有使用 CertCreateSelfSignCertificate
的现有代码方法,结合NCryptOpenStorageProvider
和 NCryptCreatePersistedKey
创建 key 对。
我现在面临的问题是,上述组合创建了一个 key ,该 key 最终出现在 Windows 加密存储中。我明确不想在那里存储 key ,我希望证书和私钥都在内存中,因为我计划将它们写入我们自己选择的加密/ protected 存储。
据我所知,BCrypt 系列函数专为内存使用而设计,我确实可以使用 BCryptGenerateKeyPair
执行此操作,但 CertCreateSelfSignCertificate
无法正常工作,因为它需要 key 存储提供程序。
有什么办法可以解决吗?我在想要么尝试以某种方式创建一个临时的内存中 key 存储提供程序,要么以困难的方式进行操作并使用对 CryptEncodeObjectEx
的复杂调用链自己构建整个 X509 证书 blob。 .关于这类东西的文档/引用和示例代码很糟糕,尽管进行了广泛的谷歌搜索,我还是很难找到任何东西:-(
对于可能有用的不同想法或示例代码的任何帮助将不胜感激
最佳答案
以下代码是我制作的一个应用程序中的确切代码(除了对代码中的应用程序名称进行了一些更改。)
它在内存中创建一个自签名证书并将其添加到本地系统存储中。进行一些调整,您可以获得证书上下文本身。它使用 CNG Next Generation API 来保持现代化。
bool GenerateSelfSignedCertificate()
{
auto result{ false };
CERT_NAME_BLOB nameBlob{ 0 };
CERT_EXTENSIONS certExtensions{ 0 };
NCRYPT_PROV_HANDLE providerHandle{ 0 };
NCRYPT_KEY_HANDLE keyHandle{ 0 };
PCCERT_CONTEXT certContext{ nullptr };
HCERTSTORE certStore{ nullptr };
CRYPT_KEY_PROV_INFO keyProvInfo{
const_cast<LPWSTR>(L"MyService_Key"), const_cast<LPWSTR>(MS_KEY_STORAGE_PROVIDER),
0, NCRYPT_SILENT_FLAG, 0, nullptr, AT_KEYEXCHANGE
};
if (!CertStrToNameW(X509_ASN_ENCODING, L"CN=MyService", 0, nullptr, nameBlob.pbData,
&nameBlob.cbData, nullptr))
goto fail;
nameBlob.pbData = new UCHAR[nameBlob.cbData];
if (!CertStrToNameW(X509_ASN_ENCODING, L"CN=MyService", 0, nullptr, nameBlob.pbData,
&nameBlob.cbData, nullptr))
goto fail;
if (NCryptOpenStorageProvider(&providerHandle, MS_KEY_STORAGE_PROVIDER, 0) != ERROR_SUCCESS)
goto fail;
if (NCryptCreatePersistedKey(providerHandle, &keyHandle, BCRYPT_RSA_ALGORITHM, L"MyService_Key",
AT_KEYEXCHANGE, 0) != ERROR_SUCCESS)
goto fail;
if (NCryptFinalizeKey(keyHandle, NCRYPT_SILENT_FLAG) != ERROR_SUCCESS)
goto fail;
certContext = CertCreateSelfSignCertificate(keyHandle, &nameBlob, 0, &keyProvInfo, nullptr,
nullptr, nullptr, &certExtensions);
if (!certContext)
goto fail;
certStore = CertOpenSystemStoreW(NULL, L"MY");
if (!certStore)
goto fail;
if (!CertAddCertificateContextToStore(certStore, certContext, CERT_STORE_ADD_REPLACE_EXISTING, nullptr))
goto fail;
result = true;
fail:
delete[] nameBlob.pbData;
if (keyHandle)
OutputDebugStringW(L"NCryptFinalizeKey successfully finalized the key for use in the certificate.\r\n");
if (providerHandle)
NCryptFreeObject(providerHandle);
if (certStore)
CertCloseStore(certStore, 0);
if (certContext)
CertFreeCertificateContext(certContext);
return result;
}
如果这对你有帮助,请告诉我。谢谢。
关于c++ - Microsoft CNG - 使用 BCrypt 函数在内存中创建自签名证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59638544/