典型的 CNG 编程
CNG API 实现可扩展提供程序模型,该模型允许通过指定所需的加密算法而不是特定提供程序来加载提供程序。 优点是可以替换或升级算法提供程序,无需以任何方式更改代码即可使用新提供程序。 此外,如果将来确定某些算法不安全,则可以安装该算法的更安全版本,而不会影响代码。 大多数 CNG API 都需要提供程序或提供程序创建的对象。
将 CNG API 用于加密基元作所涉及的典型步骤如下所示:
- 打开算法提供程序
- 获取或设置算法属性
- 创建或导入密钥
- 执行加密作
- 关闭算法提供程序
有关详细信息,请参阅编程示例。
打开算法提供程序
BCryptOpenAlgorithmProvider 函数提供在后续 CNG API 中使用的算法提供程序句柄,例如 BCryptCreateHash 或 BCryptGenerateKeyPair。
获取或设置算法属性
可以使用算法提供程序句柄获取算法的实现详细信息,例如密钥大小或当前作模式。 可以使用 BCryptGetProperty 函数获取特定属性。
还可以修改算法的属性。 例如,如果要将 ECB 块密码链与 AES 一起使用,请将 AES 算法的 BCRYPT_CHAINING_MODE 属性设置为 BCRYPT_CHAIN_MODE_ECB;该属性分配给使用此算法句柄创建的所有 AES 密钥,而无需配置每个 AES 密钥。 可以使用 BCryptSetProperty 函数修改这些属性。
创建或导入密钥
根据所使用的算法类型,可能需要创建或加载密钥。 例如,BCryptEncrypt 函数采用第一个参数的键句柄。 如果希望该函数使用对称加密算法(如 AES)加密数据,则必须首先获取密钥。 获取密钥的方式取决于所使用的算法类型和密钥的源。
可以使用 BCryptGenerateSymmetricKey 和 BCryptGenerateKeyPair 函数创建临时密钥。 还可以使用 BCryptImportKey 和 BCryptImportKeyPair 函数从内存 BLOB 导入临时密钥。
对于持久化密钥,可以使用密钥存储函数加载密钥存储提供程序,然后创建或加载密钥。 还可以使用这些函数为任何容器名称传递 NULL 来创建或加载临时密钥。 有关密钥存储函数的详细信息,请参阅 CNG 密钥存储函数。
执行加密作
现在可以分别使用 BCryptEncrypt 或 BCryptDecrypt 函数执行加密作,例如加密或解密数据。
关闭算法提供程序
不再需要提供程序时,必须将句柄传递给 BCryptCloseAlgorithmProvider 函数以关闭提供程序。 这会导致提供程序释放为该算法提供程序实例分配的任何资源。 关闭提供程序句柄后,不能重复使用。
加载提供程序可能是一个相对耗时的过程。 因此,应缓存将在应用程序的生存期内多次引用的任何提供程序句柄。
编程示例
以下示例介绍如何使用 CNG 执行特定加密作。
- 使用 CNG 创建哈希
- 使用 CNG 签名数据
- 使用 CNG 加密数据