将原始函数与存储在 Microsoft KSP 中的密钥一起使用
Using primitive function with key stored in Microsoft KSP
我的问题是关于 CNG API 和 Microsoft 提供商的用例。我不写代码示例是因为我请求您帮助我了解在我的应用程序中使用 CNG API 与 CSP API.
的最佳方式
我构建了一个使用通过以下步骤存储的对称密钥的应用程序:
- 使用 CertFindCertificateInStore
在 "My" 存储中枚举证书
- 对于找到的每个证书,使用 CertGetCertificateContextProperty
询问私钥信息
- 对于找到的每个私钥信息,存储提供者名称pwszProvName和容器名称pwszContainerName
然后,当找到密钥时,我的应用程序使用使用 CSP API 找到的私钥执行签名功能:
- 使用 CryptAcquireContext 和 pwszProvName 和 pwszContainerName
初始化提供程序操作
- 使用 CSP 函数计算签名:CryptCreateHash、CryptHashData 和 CryptSignHash
CSP 功能一切正常。
现在我尝试使用CNG进行签名操作API:
- 使用 NCryptOpenStorageProvider 和 pwszProvName
初始化提供程序操作
- 使用 CNG 函数 BCryptOpenAlgorithmProvider 打开算法提供程序失败 STATUS_NOT_FOUND
当私钥存储在 Microsoft 软件密钥存储提供程序 中时会发生此错误。
阅读 Microsoft 文档,我了解到该类型的提供程序是 KSP 提供程序,并且仅具有密钥管理功能。这就是为什么当我尝试原始函数时失败的原因,我需要使用 "Primitive Provider".
我按照这些设置找到了使用 CNG 提供程序的方法:
- Windows Server 2008:创建具有提供商要求的证书模板(在 "encryption" 选项卡上)。唯一可用的提供商是“Microsoft Software Key Storage Provider
- Windows 7:用户要求生成密钥,密钥存储在Microsoft KSP中。
所以这是我的问题:
"Microsoft Software Key Storage Provider"无法执行原始功能正常吗?
如果我不能使用 Microsoft KSP(它是 KSP 提供商)执行原始功能(签名、加密、解密、散列),我如何才能让我的私钥在 Microsoft原始提供者?
我的麻烦在于,对于 CSP API,默认的 Microsoft CSP 提供程序执行签名(以及解密、加密等)功能。但是对于 CNG API,默认提供程序仅执行密钥存储管理。
对于非对称密钥,CNG 密钥存储提供程序支持的功能与原始提供程序的功能相当,当然除了 KSP(密钥存储提供程序)允许您保存和加载密钥这一事实。
事实上,执行加密操作的 KSP API 调用看起来与原始操作非常相似,只是 KSP 以 N
开头,而原始操作以 [=11 开头=].
例如:
- NCryptSignHash for KSP signing
- NCryptSecretAgreement for KSP secret agreement
- NCryptEncrypt for KSP asymmetric encryption
KSP 缺少的是对称功能(包括散列),这可能是产生混淆的地方。与 CAPI (CSP/Crypto API) 相比,CNG 签名函数更底层一些——您首先分别对数据进行哈希处理,然后将该哈希字节块传递给 NCryptSignHash
(没有像 CAPI 中那样的散列对象句柄)。
重申一下,因为这对于来自 CAPI 的人来说是一个混淆的来源,您可以与任何原始提供者 MS_PRIMITIVE_PROVIDER
或第三方提供者进行散列,然后将结果传递给任何密钥存储提供程序的 NCryptSignHash
,因为它只是数据字节,谁进行散列并不重要。传递给 NCryptSignHash
的 NCRYPT_KEY_HANDLE
决定了使用什么 KSP 进行签名;没有 HCRYPTHASH
的 CNG 等价物传递给 NCryptSignHash
.
所以,如果你想用 KSP 签名,你应该先用原始提供者对要签名的消息进行哈希处理(使用 BCryptCreateHash
/BCryptHashData
/BCryptFinishHash
),并将结果传递给 NCryptSignHash
.
我的问题是关于 CNG API 和 Microsoft 提供商的用例。我不写代码示例是因为我请求您帮助我了解在我的应用程序中使用 CNG API 与 CSP API.
的最佳方式我构建了一个使用通过以下步骤存储的对称密钥的应用程序:
- 使用 CertFindCertificateInStore 在 "My" 存储中枚举证书
- 对于找到的每个证书,使用 CertGetCertificateContextProperty 询问私钥信息
- 对于找到的每个私钥信息,存储提供者名称pwszProvName和容器名称pwszContainerName
然后,当找到密钥时,我的应用程序使用使用 CSP API 找到的私钥执行签名功能:
- 使用 CryptAcquireContext 和 pwszProvName 和 pwszContainerName 初始化提供程序操作
- 使用 CSP 函数计算签名:CryptCreateHash、CryptHashData 和 CryptSignHash
CSP 功能一切正常。
现在我尝试使用CNG进行签名操作API:
- 使用 NCryptOpenStorageProvider 和 pwszProvName 初始化提供程序操作
- 使用 CNG 函数 BCryptOpenAlgorithmProvider 打开算法提供程序失败 STATUS_NOT_FOUND
当私钥存储在 Microsoft 软件密钥存储提供程序 中时会发生此错误。 阅读 Microsoft 文档,我了解到该类型的提供程序是 KSP 提供程序,并且仅具有密钥管理功能。这就是为什么当我尝试原始函数时失败的原因,我需要使用 "Primitive Provider".
我按照这些设置找到了使用 CNG 提供程序的方法:
- Windows Server 2008:创建具有提供商要求的证书模板(在 "encryption" 选项卡上)。唯一可用的提供商是“Microsoft Software Key Storage Provider
- Windows 7:用户要求生成密钥,密钥存储在Microsoft KSP中。
所以这是我的问题:
"Microsoft Software Key Storage Provider"无法执行原始功能正常吗?
如果我不能使用 Microsoft KSP(它是 KSP 提供商)执行原始功能(签名、加密、解密、散列),我如何才能让我的私钥在 Microsoft原始提供者?
我的麻烦在于,对于 CSP API,默认的 Microsoft CSP 提供程序执行签名(以及解密、加密等)功能。但是对于 CNG API,默认提供程序仅执行密钥存储管理。
对于非对称密钥,CNG 密钥存储提供程序支持的功能与原始提供程序的功能相当,当然除了 KSP(密钥存储提供程序)允许您保存和加载密钥这一事实。
事实上,执行加密操作的 KSP API 调用看起来与原始操作非常相似,只是 KSP 以 N
开头,而原始操作以 [=11 开头=].
例如:
- NCryptSignHash for KSP signing
- NCryptSecretAgreement for KSP secret agreement
- NCryptEncrypt for KSP asymmetric encryption
KSP 缺少的是对称功能(包括散列),这可能是产生混淆的地方。与 CAPI (CSP/Crypto API) 相比,CNG 签名函数更底层一些——您首先分别对数据进行哈希处理,然后将该哈希字节块传递给 NCryptSignHash
(没有像 CAPI 中那样的散列对象句柄)。
重申一下,因为这对于来自 CAPI 的人来说是一个混淆的来源,您可以与任何原始提供者 MS_PRIMITIVE_PROVIDER
或第三方提供者进行散列,然后将结果传递给任何密钥存储提供程序的 NCryptSignHash
,因为它只是数据字节,谁进行散列并不重要。传递给 NCryptSignHash
的 NCRYPT_KEY_HANDLE
决定了使用什么 KSP 进行签名;没有 HCRYPTHASH
的 CNG 等价物传递给 NCryptSignHash
.
所以,如果你想用 KSP 签名,你应该先用原始提供者对要签名的消息进行哈希处理(使用 BCryptCreateHash
/BCryptHashData
/BCryptFinishHash
),并将结果传递给 NCryptSignHash
.