开放SSL

密码学和 SSL/TLS 工具包

EVP_KDF-HKDF

名称

EVP_KDF-HKDF - HKDF EVP_KDF 实现

描述

通过 EVP_KDF API 支持计算 HKDF KDF。

EVP_KDF-HKDF 算法实现了 HKDF 密钥推导函数。HKDF 遵循“提取然后扩展”模式,其中 KDF 在逻辑上包含两个模块。第一阶段采用输入密钥材料并从中“提取”一个固定长度的伪随机密钥 K。第二阶段“扩展”密钥 K 以生成多个额外的伪随机密钥(KDF 的输出)。

身份

"HKDF" 是此实现的名称;它可以与 EVP_KDF_fetch() 函数一起使用。

支持的参数

支持的参数是

"properties" (OSSL_KDF_PARAM_PROPERTIES) <UTF8 字符串>
"digest" (OSSL_KDF_PARAM_DIGEST) <UTF8 字符串>
"key" (OSSL_KDF_PARAM_KEY) <八位字节串>
"salt" (OSSL_KDF_PARAM_SALT) <八位字节串>

这些参数的工作原理如 "参数" 在 EVP_KDF(3) 中所述

"info" (OSSL_KDF_PARAM_INFO) <八位字节串>

此参数设置信息值。上下文信息缓冲区的长度不能超过 1024 字节;这对于 HKDF 的任何正常使用都应该足够了。

"mode" (OSSL_KDF_PARAM_MODE) <UTF8 字符串> 或 <整数>

此参数设置 HKDF 操作的模式。目前定义了三种模式

"EXTRACT_AND_EXPAND" 或 EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND

这是默认模式。在为 HKDF 设置的 EVP_KDF_CTX 上调用 EVP_KDF_derive(3) 将一次执行提取和扩展操作。返回的派生密钥将是扩展操作后的结果。不会返回中间固定长度的伪随机密钥 K。

在此模式下,必须在派生密钥之前设置摘要、密钥、盐和信息值,否则会发生错误。

"EXTRACT_ONLY" 或 EVP_KDF_HKDF_MODE_EXTRACT_ONLY

在此模式下,调用 EVP_KDF_derive(3) 只会执行提取操作。返回的值将是中间固定长度的伪随机密钥 K。keylen 参数必须与 K 的大小匹配,可以通过在设置模式和摘要后调用 EVP_KDF_CTX_get_kdf_size() 来查找。

必须在派生密钥之前设置摘要、密钥和盐值,否则会发生错误。

"EXPAND_ONLY" 或 EVP_KDF_HKDF_MODE_EXPAND_ONLY

在此模式下,调用 EVP_KDF_derive(3) 只会执行扩展操作。输入密钥应设置为先前提取操作返回的中间固定长度的伪随机密钥 K。

必须在派生密钥之前设置摘要、密钥和信息值,否则会发生错误。

注意事项

可以通过调用以下方法获取 HKDF 的上下文

EVP_KDF *kdf = EVP_KDF_fetch(NULL, "HKDF", NULL);
EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf);

HKDF 扩展操作的输出长度通过 EVP_KDF_derive(3) 函数的 keylen 参数指定。当使用 EVP_KDF_HKDF_MODE_EXTRACT_ONLY 时,keylen 参数必须等于中间固定长度的伪随机密钥的大小,否则会发生错误。对于该模式,可以通过在 EVP_KDF_CTX 上设置模式和摘要后调用 EVP_KDF_CTX_get_kdf_size() 来查找固定输出大小。

示例

此示例使用 SHA-256 以及密钥“secret”、盐值“salt”和信息值“label”派生 10 字节

EVP_KDF *kdf;
EVP_KDF_CTX *kctx;
unsigned char out[10];
OSSL_PARAM params[5], *p = params;

kdf = EVP_KDF_fetch(NULL, "HKDF", NULL);
kctx = EVP_KDF_CTX_new(kdf);
EVP_KDF_free(kdf);

*p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
                                        SN_sha256, strlen(SN_sha256));
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
                                         "secret", (size_t)6);
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO,
                                         "label", (size_t)5);
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
                                         "salt", (size_t)4);
*p = OSSL_PARAM_construct_end();
if (EVP_KDF_derive(kctx, out, sizeof(out), params) <= 0) {
    error("EVP_KDF_derive");
}

EVP_KDF_CTX_free(kctx);

符合

RFC 5869

另请参阅

EVP_KDF(3), EVP_KDF_CTX_new(3), EVP_KDF_CTX_free(3), EVP_KDF_CTX_get_kdf_size(3), EVP_KDF_CTX_set_params(3), EVP_KDF_derive(3), "参数" 在 EVP_KDF(3) 中, EVP_KDF-TLS13_KDF(7)

历史记录

此功能在 OpenSSL 3.0 中添加。

版权所有 2016-2021 OpenSSL 项目作者。保留所有权利。

根据 Apache 许可证 2.0(“许可证”)许可。除非遵守许可证,否则您不得使用此文件。您可以在源代码分发中的 LICENSE 文件或 https://www.openssl.org/source/license.html 中获取副本。