将原始函数与存储在 Microsoft KSP 中的密钥一起使用

Using primitive function with key stored in Microsoft KSP

我的问题是关于 CNG API 和 Microsoft 提供商的用例。我不写代码示例是因为我请求您帮助我了解在我的应用程序中使用 CNG API 与 CSP API.

的最佳方式

我构建了一个使用通过以下步骤存储的对称密钥的应用程序:

然后,当找到密钥时,我的应用程序使用使用 CSP API 找到的私钥执行签名功能:

CSP 功能一切正常。

现在我尝试使用CNG进行签名操作API:

当私钥存储在 Microsoft 软件密钥存储提供程序 中时会发生此错误。 阅读 Microsoft 文档,我了解到该类型的提供程序是 KSP 提供程序,并且仅具有密钥管理功能。这就是为什么当我尝试原始函数时失败的原因,我需要使用 "Primitive Provider".

我按照这些设置找到了使用 CNG 提供程序的方法:

所以这是我的问题:

我的麻烦在于,对于 CSP API,默认的 Microsoft CSP 提供程序执行签名(以及解密、加密等)功能。但是对于 CNG API,默认提供程序仅执行密钥存储管理。

对于非对称密钥,CNG 密钥存储提供程序支持的功能与原始提供程序的功能相当,当然除了 KSP(密钥存储提供程序)允许您保存和加载密钥这一事实。

事实上,执行加密操作的 KSP API 调用看起来与原始操作非常相似,只是 KSP 以 N 开头,而原始操作以 [=11 开头=].

例如:

KSP 缺少的是对称功能(包括散列),这可能是产生混淆的地方。与 CAPI (CSP/Crypto API) 相比,CNG 签名函数更底层一些——您首先分别对数据进行哈希处理,然后将该哈希字节块传递给 NCryptSignHash(没有像 CAPI 中那样的散列对象句柄)。

重申一下,因为这对于来自 CAPI 的人来说是一个混淆的来源,您可以与任何原始提供者 MS_PRIMITIVE_PROVIDER 或第三方提供者进行散列,然后将结果传递给任何密钥存储提供程序的 NCryptSignHash,因为它只是数据字节,谁进行散列并不重要。传递给 NCryptSignHashNCRYPT_KEY_HANDLE 决定了使用什么 KSP 进行签名;没有 HCRYPTHASH 的 CNG 等价物传递给 NCryptSignHash.

所以,如果你想用 KSP 签名,你应该先用原始提供者对要签名的消息进行哈希处理(使用 BCryptCreateHash/BCryptHashData/BCryptFinishHash),并将结果传递给 NCryptSignHash.