典型的 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 执行特定的加密操作。