我们之前开发了一个 RSA MSCAPI CSP 用于经典的 Windows 加密 API,并且多年来一直运行良好。不幸的是,在 AES 加密的情况下,较新版本的 Outlook 拒绝使用此 CSP。它仍然支持 3DES 但不支持 AES。这很奇怪,因为它实际上不是处理对称解密的 CSP,但显然微软不想支持 MS-CAPI 的 AES 案例。对于 AES 支持,RSA 密钥需要采用较新的提供程序类型,即符合 CNG 框架的密钥存储提供程序。好的,但问题是:如何确保拥有依赖 MS-CAPI 接口的软件的客户端的向后兼容性?
根据我的理解(这可能是错误的),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 只希望引用新的提供程序,而旧程序只能与旧提供程序一起使用。遗留程序将不具有此逻辑,因此在 CNG 提供程序中的密钥的情况下将失败。这意味着不可能同时满足新程序和旧程序的需求,因为您必须在 CERT_KEY_PROV_INFO_PROP_ID 中输入对旧提供程序或新提供程序的引用,但您不能同时拥有两者。Outlook 只希望引用新的提供程序,而旧程序只能与旧提供程序一起使用。遗留程序将不具有此逻辑,因此在 CNG 提供程序中的密钥的情况下将失败。这意味着不可能同时满足新程序和旧程序的需求,因为您必须在 CERT_KEY_PROV_INFO_PROP_ID 中输入对旧提供程序或新提供程序的引用,但您不能同时拥有两者。Outlook 只希望引用新的提供程序,而旧程序只能与旧提供程序一起使用。
但这真的可以吗,还是我缺少某些东西或我的理解有一些错误?微软似乎有多种方法可以帮助程序具有某种类型的互操作性(例如,旧程序可以使用旧 API 使用新的 KSP)。