使用存储在Microsoft KSP中的密钥的原始函数

时间:2015-01-23 15:26:36

标签: c++ certificate key cng

我的问题是关于CNG API和Microsoft提供商的用例。我没有编写代码示例,因为与CSP API相比,我要求您提供有关在我的应用程序中使用CNG API的最佳方法的帮助。

我构建了一个使用以下步骤存储的symetric键的应用程序:

  • 枚举"我的"中的证书使用 CertFindCertificateInStore
  • 存储
  • 找到每个证书,使用 CertGetCertificateContextProperty
  • 询问私钥信息
  • 找到每个私钥信息,存储提供程序名称​​ pwszProvName 和容器名称​​ pwszContainerName

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

  • 使用 pwszProvName pwszContainerName
  • 使用 CryptAcquireContext 初始化提供程序操作
  • 使用CSP函数计算签名: CryptCreateHash CryptHashData CryptSignHash

CSP功能一切正常。

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

  • 使用 pwszProvName
  • 使用 NCryptOpenStorageProvider 初始化提供程序操作
  • 使用CNG函数 BCryptOpenAlgorithmProvider 的开放算法提供程序失败, STATUS_NOT_FOUND

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

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

  • Windows Server 2008:创建一个包含提供者要求的证书模板(在"加密"选项卡上)。并且唯一可用的提供商是" Microsoft软件密钥存储提供商
  • Windows 7:用户要求密钥生成,密钥存储在Microsoft KSP中。

所以这是我的问题:

  • 是否正常我无法使用" Microsoft软件密钥存储提供商"

  • 如果我无法使用Microsoft KSP(KSP提供商)执行原始功能(签名,加密,解密,哈希),如何在Microsoft原始提供程序中存储和管理我的私钥?

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

1 个答案:

答案 0 :(得分:1)

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

事实上,KSP API调用加密操作与原始操作看起来大致相同,除了KSP以N开头,原始操作以B开头。

例如:

KSP中缺少的 是对称功能(包括散列),这可能是出现混淆的地方。与CAPI(CSP / Crypto API)相比,CNG签名函数更低级 - 首先分别对数据进行散列,然后将该散列字节块传递给NCryptSignHash(没有像CAPI中那样的散列对象句柄)

要重新迭代,因为这是来自CAPI的人的混淆源,您可以与任何原始提供程序MS_PRIMITIVE_PROVIDER或第三方提供程序进行哈希,然后将结果传递给任何密钥存储提供者的NCryptSignHash,因为它只是数据的字节,所以进行散列并不重要。传递给NCRYPT_KEY_HANDLE的{​​{1}}确定了KSP用于签名的内容;没有CNG等效的NCryptSignHash传递给HCRYPTHASH

因此,如果您想使用KSP进行签名,则应首先使用原始提供程序(使用NCryptSignHash / BCryptCreateHash / BCryptHashData)对要首先签名的邮件进行哈希处理,然后通过结果为BCryptFinishHash