典型 CNG 编程

CNG API 实现可扩展的提供程序模型,该模型允许通过指定所需的加密算法而不是特定提供程序来加载提供程序。 优点是可以替换或升级算法提供程序,并且无需以任何方式更改代码即可使用新的提供程序。 此外,如果确定某些算法将来不安全,则可以安装该算法的更安全版本,而不会影响代码。 大多数 CNG API 需要提供程序或提供程序创建的对象。

将 CNG API 用于加密基元操作所涉及的典型步骤如下:

  1. 打开算法提供程序
  2. 获取或设置算法属性
  3. 创建或导入密钥
  4. 执行加密操作
  5. 关闭算法提供程序

有关详细信息,请参阅编程示例。

打开算法提供程序

BCryptOpenAlgorithmProvider 函数提供用于后续 CNG API(如 BCryptCreateHashBCryptGenerateKeyPair)的算法提供程序句柄。

获取或设置算法属性

可以使用算法提供程序句柄获取算法的实现详细信息,例如密钥大小或当前操作模式。 使用 BCryptGetProperty 函数获取特定属性。

还可以修改算法的属性。 例如,如果要将 ECB 块密码链与 AES 配合使用,请将 AES 算法 的 BCRYPT_CHAINING_MODE 属性设置为 BCRYPT_CHAIN_MODE_ECB;属性分配给使用此算法句柄创建的所有 AES 密钥,而无需配置每个 AES 密钥。 使用 BCryptSetProperty 函数修改这些属性。

创建或导入密钥

根据所使用的算法类型,可能需要创建或加载密钥。 例如, BCryptEncrypt 函数采用第一个参数的键句柄。 如果希望该函数使用对称加密算法(如 AES)加密数据,必须先获取密钥。 获取密钥的方式取决于所使用的算法类型和密钥的源。

可以使用 BCryptGenerateSymmetricKeyBCryptGenerateKeyPair 函数创建临时密钥。 还可以使用 BCryptImportKey 和 BCryptImportKeyPair 函数从内存 BLOB 导入临时密钥。

对于持久化密钥,请使用密钥存储函数加载密钥存储提供程序,然后创建或加载密钥。 还可以使用这些函数通过为任何容器名称传递 NULL 来创建或加载临时密钥。 有关密钥存储函数的详细信息,请参阅 CNG 密钥存储函数

执行加密操作

现在,可以执行加密操作,例如分别使用 BCryptEncryptBCryptDecrypt 函数加密或解密数据。

关闭算法提供程序

当不再需要提供程序时,必须将句柄传递给 BCryptCloseAlgorithmProvider 函数才能关闭提供程序。 这会导致提供程序释放已为该算法提供程序实例分配的任何资源。 关闭提供程序句柄后,不能重复使用该句柄。

加载提供程序可能是一个相对耗时的过程。 因此,应缓存将在应用程序生存期内多次引用的任何提供程序句柄。

编程示例

以下示例介绍如何使用 CNG 执行特定加密操作。