Microsoft MSCAPI-CSP和CNG兼容性

时间:2018-11-06 11:44:41

标签: cng mscapi

我们以前已经开发了可与经典Windows加密API一起使用的RSA MSCAPI CSP,并且多年来效果良好。不幸的是,在AES加密的情况下,较新版本的Outlook拒绝使用此CSP。它仍然支持3DES,但不支持AES。这很奇怪,因为实际上不是由CSP处理对称解密,但是显然Microsoft不想为MS-CAPI支持AES情况。为了支持AES,RSA密钥必须采用较新的提供程序类型,即符合CNG框架的密钥存储提供程序。 好的,但是要注意的是:对于具有依赖于MS-CAPI接口的软件的客户端,如何确保向后兼容?
根据我的理解(可能是错误的),证书存储与MSCAPI和CNG相同。区别在于如何引用私钥。证书的属性为“ CERT_KEY_PROV_INFO_PROP_ID”,其中包含许多字段,包括提供程序名称,容器名称和提供程序类型。如果提供程序类型为“ 0”(在旧API中不是合法值),则表明指定的提供程序实际上是新的CNG提供程序之一。

旧的应用程序将使用旧版功能(即CryptAcquireContext())使用CERT_KEY_PROV_INFO_PROP_ID中的值来获取加密上下文。但是,在CNG提供程序(即提供程序类型= 0)的情况下,此函数将失败-在这里看来程序将不得不使用新的CNG函数(即NCryptOpenStorageProvider,NCryptOpenKey等)再次从CERT_KEY_PROV_INFO_PROP_ID中传入值。因此,如果这种理解/测试是正确的,则意味着从旧版应用程序的角度来看,无法迁移到CNG提供者,并且仍然具有相同的证书/密钥。我无法在文档中明确找到此声明,但是似乎每个应用程序都需要查看CERT_KEY_PROV_INFO_PROP_ID内容,并进行切换:如果提供程序类型= 0,则这是CNG中的密钥提供程序,以便该程序将使用新的CNG功能。另一方面,如果提供程序类型> 0,则程序应使用旧版函数。但是,当然,旧版程序将不具有此逻辑,因此在CNG提供程序中存在密钥的情况下将失败。这意味着不可能同时满足新程序和旧程序的需求,因为您必须在CERT_KEY_PROV_INFO_PROP_ID中放入旧提供程序的引用或新提供程序的引用,但您不能同时拥有两者。 Outlook只希望引用新的提供程序,而旧程序只能与旧的提供程序一起使用。

但是这真的可以吗?或者我缺少某些东西或者我的理解中有错误吗?微软似乎可以通过多种方式来帮助程序具有某种类型的互操作性(例如,旧程序可以使用旧API使用新的KSP)。

1 个答案:

答案 0 :(得分:0)

据我所知,没有解决方案可以完全按照所述解决问题。但是新的CNG API提供了一个NCryptTranslateHandle()函数,程序可以使用该函数将旧式引用从CERT_KEY_PROV_INFO_PROP_ID转换为相应KSP的句柄。当KSP注册自己时,它可以指定一个或多个“别名”,即它是别名的经典MS-CAPI提供程序的名称。如果程序随后从经典MS-CAPI CSP的句柄上调用NCryptTranslateHandle()句柄,则Windows将查看是否有已安装的KSP将其自身注册为该CSP的别名。如果是这样,则该句柄将转换为相应CSP的句柄。然后,程序可以继续并在该句柄上使用新的CNG函数,这将调用新的提供程序。

该怎么办:1)在证书中保留CERT_KEY_PROV_INFO_PROP_ID引用的内容(即指向旧的CSP),2)注册具有旧CSP作为别名的KSP提供程序(不要在其中包含SDK)现在是我的最爱,但这是您可以提供的注册参数之一。如果找不到,请告诉我!)

对此有点不满意的是,它们全部取决于调用NCryptTranslateHandle()句柄的调用程序。很老的遗留程序-在CNG出现之前编写的-显然不会调用此函数,因为该函数在开发时就不存在。但是Microsoft Outlook(至少是较新的功能)(这是一个非常常见的用例)确实知道调用此功能。因此,如果您提供了我在前面的段落中描述的双CSP + KSP解决方案,那么它将可以正常工作:由于使用了转换功能,Outlook最终将通过KSP API调用您的解决方案。

实施解决方案时,应先编写程序对其进行测试,然后再使用Outlook测试。让程序以老式的方式获取键的句柄,然后使用翻译功能并看到您有一个句柄,然后在生成的句柄上使用KSP函数。