我们以前开发了一个RSA MSCAPI,用于与经典的Windows密码API一起使用,而且多年来一直运行良好。不幸的是,更新版本的Outlook拒绝在AES加密的情况下使用此CSP。它仍然支持3 AES,但不支持AES。这很奇怪,因为处理对称解密的实际上不是CSP,但显然微软不想支持MS-CAPI的AES-case。对于AES-支持,RSA密钥需要在更新的提供程序类型中,即符合CNG框架的密钥存储提供程序中。好吧,但问题是:我如何确保客户端向后兼容,这些客户端的软件依赖于MS接口?
根据我的理解(这可能是错误的),证书存储是相同的MSCAPI和CNG。不同之处在于如何引用私钥。证书的属性"CERT_KEY_PROV_INFO_PROP_ID“包含许多字段,包括提供程序名称、容器名称和提供程序类型。如果提供程序类型为"0“(在旧API中不是合法值),则指示指定的提供者实际上是新的CNG提供程序之一。
一个旧的应用程序将使用来自CERT_KEY_PROV_INFO_PROP_ID的值来使用遗留函数(即CryptAcquireContext() )获取密码上下文。但是,这个函数在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只需要对新提供程序的引用,而旧程序只能使用旧的提供程序。
但是,这真的是这样吗?或者我的理解中有什么东西是我遗漏的,或者是一些错误?微软似乎有多种方法来帮助程序具有某种类型的互操作性(例如,旧的程序可以使用新的KSP使用旧的API)。
发布于 2019-08-05 19:19:46
据我所知,没有任何解决办法能像所说的那样准确地解决问题。但是新的CNG提供了一个函数NCryptTranslateHandle(),程序可以使用该函数将旧风格的引用从CERT_KEY_PROV_INFO_PROP_ID转换到相应的KSP句柄。当KSP注册自己时,它可以指定一个或多个“别名”,即它是别名的经典MS提供者的名称。如果程序然后从经典的MS调用句柄上的NCryptTranslateHandle()句柄,Windows将查看是否有已安装的KSP已注册为该CSP的别名。如果是这样,该句柄将被转换为对应CSP的句柄。然后,程序可以继续并在该句柄上使用新的CNG函数,这将调用新的提供者。
那么应该做什么: 1)在证书中保留它现在的CERT_KEY_PROV_INFO_PROP_ID引用(即指向旧的CSP),2)注册一个KSP提供者,它的别名是旧的CSP (现在我面前没有SDK,但它是您可以提供的注册参数之一)。如果你找不到就告诉我!)
有一点令人不满意的是,这一切都取决于调用程序调用NCryptTranslateHandle()句柄。一个旧的遗留程序--在CNG出现之前编写的--显然不会调用这个函数,因为这个函数在开发时并不存在。但是Microsoft (至少是较新的函数)--这是一个非常常见的用例--知道如何调用这个函数。因此,如果您提供一个双CSP+KSP解决方案,正如我在前面几段中所描述的那样,它会正常工作:由于它使用了转换函数,它最终将通过KSP调用您的解决方案。
在实现解决方案时,您应该在使用Outlook进行测试之前编写一个程序来测试它。让程序以老式的方式获得键的句柄,然后使用转换函数,然后看到您得到一个句柄,然后在结果句柄上使用KSP函数。
https://stackoverflow.com/questions/53171248
复制相似问题