MS CryptoAPI-错误为0x80090016(NTE_BAD_密钥集)的机器密钥库以及certreq创建的密钥 总结
我使用CSR创建了一个PKCS#10,并设置了选项MS CryptoAPI-错误为0x80090016(NTE_BAD_密钥集)的机器密钥库以及certreq创建的密钥 总结,c,openssl,cryptoapi,C,Openssl,Cryptoapi,我使用CSR创建了一个PKCS#10,并设置了选项Exportable=TRUE。这将在位置请求下成功创建密钥。我还有一个有效的证书,其密钥位于MY。如果我尝试访问其中任何一个,CryptoAPI将报告错误代码0x80090016 目前,在不同访问权限下运行无法解决此问题 目标 我的目标是获得My和REQUEST中的两个键。如果我对其中任何一个调用cryptaccesscontexta(),它都会失败 系统 Windows 7 x64 示例源代码 我的完整代码如下所示: hStore = Cer
Exportable=TRUE
。这将在位置请求下成功创建密钥。我还有一个有效的证书,其密钥位于MY
。如果我尝试访问其中任何一个,CryptoAPI将报告错误代码0x80090016
目前,在不同访问权限下运行无法解决此问题
目标
我的目标是获得My
和REQUEST
中的两个键。如果我对其中任何一个调用cryptaccesscontexta()
,它都会失败
系统
Windows 7 x64
示例源代码
我的完整代码如下所示:
hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE, "REQUEST");
pCert = CertFindCertificateInStore(hStore, X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR_A, "CERTIFICATE_SUBJECT", NULL);
CertGetCertificateContextProperty(pCert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &len);
pinfo = (CRYPT_KEY_PROV_INFO *) malloc(len);
CertGetCertificateContextProperty(pCert, CERT_KEY_PROV_INFO_PROP_ID, pinfo, &len);
provname = wide_to_asc(pinfo->pwszProvName);
contname = wide_to_asc(pinfo->pwszContainerName);
if(!CryptAcquireContextA(&hCryptProv, contname, provname, pinfo->dwProvType, 0)) {
err = GetLastError();
fprintf(stderr, "Error: 0x%x\n", err);
}
CryptGetUserKey(hCryptProv, pinfo->dwKeySpec, &hUserkey);
CryptAcquireContextA(&hCryptProv, contname, provname, pinfo->dwProvType, CRYPT_MACHINE_KEYSET)
此代码主要是从OpenSSL capi引擎复制的。由于引擎失败,我创建了尽可能小的代码来搜索错误
错误
如果我运行此命令,它将失败,输出错误为:0x80090016
。这意味着以下三件事之一:
- 密钥容器不存在
- 您无权访问密钥容器
- 受保护的存储服务未运行
- 已启动服务“受保护存储”
- 已验证的容器存在,并带有本地计算机的MMC和证书管理单元
- 在用户上下文中的用户存储上运行相同的代码-它起作用了
contname
变量并搜索文件找到了这些文件。我更改了对它们的权限(更准确地说,我更改了对父文件夹的权限)。虽然这解决了MY
的问题,但似乎我无法为REQUEST
更改它
这里需要注意的是,my
的容器似乎在这里:
%APPDATA%\Microsoft\Crypto\RSA\S-1-5-21-1650336054-1974872081-316617838-545102
对于请求
我在另一个地址下找到了它:
%ALLUSERSPROFILE%\Microsoft\Crypto\RSA\MachineKeys
我不确定这里的工作,所以我无法解释为什么它会把它们放在不同的位置(一个是以用户为中心的,另一个是系统文件夹)。MY
存储是通过常规管理员提示和命令certreq-new inf_file.inf cert csr.csr
创建的,在我收到证书后,我发布了certreq-accept cert.pem
。然后我用相同的命令创建了一个新的csr
不同的特权级别
我尝试使用以下权限执行我的程序:
- 我的本地用户帐户
- 管理员提示(cmd->start as administrator)
- nt权限\系统(
output)whoami
psexec.exe–ids cmd.exe
最后的话
对于如何进一步缩小这一问题的任何帮助或指导,我们将不胜感激 我终于解决了这个问题,它比我想象的要简单得多。我确信我会收到一个明确的容器名称,不需要更具体,但
cryptaccesscontext
实际上需要我传递一个标志CRYPT\u MACHINE\u KEYSET
因此,我的函数调用必须如下所示:
hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE, "REQUEST");
pCert = CertFindCertificateInStore(hStore, X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR_A, "CERTIFICATE_SUBJECT", NULL);
CertGetCertificateContextProperty(pCert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &len);
pinfo = (CRYPT_KEY_PROV_INFO *) malloc(len);
CertGetCertificateContextProperty(pCert, CERT_KEY_PROV_INFO_PROP_ID, pinfo, &len);
provname = wide_to_asc(pinfo->pwszProvName);
contname = wide_to_asc(pinfo->pwszContainerName);
if(!CryptAcquireContextA(&hCryptProv, contname, provname, pinfo->dwProvType, 0)) {
err = GetLastError();
fprintf(stderr, "Error: 0x%x\n", err);
}
CryptGetUserKey(hCryptProv, pinfo->dwKeySpec, &hUserkey);
CryptAcquireContextA(&hCryptProv, contname, provname, pinfo->dwProvType, CRYPT_MACHINE_KEYSET)
不幸的是,OpenSSL引擎不支持这一点,因此您必须自己在引擎中修改它。请参阅MSDN:“非管理员用户创建的没有此标志的密钥容器只能由创建密钥容器的用户和本地系统帐户访问。”
请在此填写详细信息: