概括
我创建了一个 PKCS#10 CSRcertreq
并设置了选项Exportable=TRUE
。这成功地在 location 下创建了一个密钥REQUEST
。我也有一个有效的证书,其中包含MY
. 如果我尝试访问其中任何一个,CryptoAPI 会报告错误代码0x80090016
。
在不同的访问权限下运行目前还不能解决这个问题。
目标
我的目标是把钥匙MY
和REQUEST
. 如果我调用CryptAcquireContextA()
其中任何一个,它就会失败。
系统
视窗 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);
这段代码大部分是从OpenSSL capi engine复制而来的。由于引擎出现故障,我创建了尽可能小的代码来搜索错误。
错误
如果我运行它,它会以输出失败Error: 0x80090016
。根据微软的说法,这意味着三件事之一:
- 密钥容器不存在。
- 您无权访问密钥容器。
- 受保护的存储服务未运行。
到目前为止我做了什么?
- 启动服务“受保护的存储”
- 已验证的容器存在 MMC 和证书管理单元
Local Computer
- 在用户上下文中的用户存储上运行相同的代码 - 它有效
文件系统权限
经过一番谷歌搜索后,我尝试更改文件系统的权限。我通过查看contname
代码的变量并搜索文件找到了这些文件。我更改了它们的权限(更准确地说,我更改了父文件夹的权限)。虽然这解决了问题MY
,但似乎我无法更改它REQUEST
。
这里的一个注意事项是我的容器MY
似乎在这里:
%APPDATA%\Microsoft\Crypto\RSA\S-1-5-21-1650336054-1974872081-316617838-545102
因为REQUEST
我在另一个地址下找到了它:
%ALLUSERSPROFILE%\Microsoft\Crypto\RSA\MachineKeys
我不确定这里的工作原理,所以我无法解释为什么它将它们放在不同的位置(一个是以用户为中心,另一个是系统文件夹)。该MY
商店是使用常规管理员提示和命令创建的certreq -new inf_file.inf cert-csr.csr
,在我收到证书后,我发布了certreq -accept cert.pem
. 然后我用相同的命令创建了一个新的 csr。
不同的权限级别
我尝试使用以下权限执行我的程序:
- 我的本地用户帐户
- 管理员提示符(cmd->以管理员身份启动)
- nt 权限\系统(
whoami
输出)
为了收到服务提示,我psexec.exe –ids cmd.exe
根据MaaSters 中心的提示执行了
最后的话
任何有关如何进一步缩小此问题的帮助或指导将不胜感激。