文章目录
🥦算法获取
为了使用算法,必须首先"获取"该算法的实现。获取是查看可用实现、应用选择条件(通过属性查询字符串)并最终选择要使用的实现的过程。
OpenSSL 支持两种类型的提取 - 显式获取和隐式获取。
🥬属性查询字符串
提取算法时,可以指定属性查询字符串来指导选择过程。例如,可以使用"provider=default"的属性查询字符串来强制选择仅考虑默认提供程序中的算法实现。
属性查询字符串可以显式指定为函数的参数。也可以使用EVP_set_default_properties函数为整个库上下文指定默认属性查询字符串。如果同时指定了默认属性和特定于函数的属性,则将它们组合在一起。特定于函数的属性将覆盖存在冲突的默认属性。
🥒显式获取
OpenSSL 库的用户从不直接向提供程序查询算法实现。相反,各种 OpenSSL API 通常具有执行该工作的显式获取函数,并且它们将适当的算法对象返回给用户。例如EVP_MD_fetch可用于显式获取摘要算法实现。当不再需要对象时,用户负责释放从函数返回的对象。
这些获取函数遵循一个相当常见的模式,其中传递了三个参数:
- 库上下文
只有在此库上下文中加载的提供程序才会被 fetch 函数考虑。如果在此库上下文中未加载任何提供程序,则默认提供程序将作为回退加载。 - 标识符
对于所有当前实现的提取函数,这是算法名称。 - 属性查询字符串
用于指导算法实现选择的属性查询字符串。
然后,获取的算法实现可以与使用它们的其他不同函数一起使用。例如,EVP_DigestInit_ex函数将一个EVP_MD对象作为参数,该对象可能是从之前对EVP_MD_fetch的调用中返回的。
🌶️隐式提取
OpenSSL 有许多函数返回没有关联实现的算法对象,例如EVP_sha256 、EVP_blake2b512或EVP_aes_128_cbc。这些是为了与3.0版之前的OpenSSL兼容,其中显式获取不可用。
当它们与EVP_DigestInit_ex或EVP_CipherInit_ex等函数一起使用时,使用的实际实现是使用默认搜索条件隐式获取的。
在某些情况下,当提供 NULL 算法参数时,也可能发生隐式提取。在这种情况下,使用默认搜索条件和与使用算法的上下文一致的算法名称隐式获取算法实现。
🌽获取示例
以下部分提供了一系列获取算法实现的示例。
在默认上下文中获取 SHA2-256 的任何可用实现。请注意,某些算法具有别名。所以"SHA256"和"SHA2-256"是同义词:
EVP_MD *md = EVP_MD_fetch(NULL, "SHA2-256", NULL);
...
EVP_MD_free(md);
在默认上下文中获取 AES-128-CBC 的任何可用实现:
EVP_CIPHER *cipher = EVP_CIPHER_fetch(NULL, "AES-128-CBC", NULL);
...
EVP_CIPHER_free(cipher);
从默认上下文中的默认提供程序获取 SHA2-256 的实现:
EVP_MD *md = EVP_MD_fetch(NULL, "SHA2-256", "provider=default");
...
EVP_MD_free(md);
获取不是来自默认上下文中的默认提供程序的 SHA2-256 实现:
EVP_MD *md = EVP_MD_fetch(NULL, "SHA2-256", "provider!=default");
...
EVP_MD_free(md);
从指定上下文中的默认提供程序获取 SHA2-256 的实现:
EVP_MD *md = EVP_MD_fetch(ctx, "SHA2-256", "provider=default");
...
EVP_MD_free(md);
将旧提供程序加载到默认上下文中,然后从中获取 WHIRLPOOL 的实现:
/* This only needs to be done once - usually at application start up */
OSSL_PROVIDER *legacy = OSSL_PROVIDER_load(NULL, "legacy");
EVP_MD *md = EVP_MD_fetch(NULL, "WHIRLPOOL", "provider=legacy");
...
EVP_MD_free(md);
请注意,在上面的示例中,属性字符串"provider=legacy"是可选的,因为假设没有加载其他提供程序,则"whirlpool"算法的唯一实现是在"legacy"提供程序中。另请注意,如果除了其他提供程序之外还需要默认提供程序,则应显式加载该提供程序:
/* This only needs to be done once - usually at application start up */
OSSL_PROVIDER *legacy = OSSL_PROVIDER_load(NULL, "legacy");
OSSL_PROVIDER *default = OSSL_PROVIDER_load(NULL, "default");
EVP_MD *md_whirlpool = EVP_MD_fetch(NULL, "whirlpool", NULL);
EVP_MD *md_sha256 = EVP_MD_fetch(NULL, "SHA2-256", NULL);
...
EVP_MD_free(md_whirlpool);
EVP_MD_free(md_sha256);