EVP_PKEY_derive调用失败无明确错误码求助(OpenSSL 1.1.1k)
问题:OpenSSL HKDF中EVP_PKEY_derive返回0且无明确错误码
修改OpenSSL官方HKDF示例代码后,调用EVP_PKEY_derive时返回0,且无法获取有效错误信息,输出为EVP_PKEY_derive: 0, error:00000000:lib(0):func(0):reason(0),使用版本为OpenSSL 1.1.1k。
测试代码
#include <openssl/err.h> #include <openssl/evp.h> #include <openssl/kdf.h> int main() { char error[1024]; if (EVP_PKEY_CTX* pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL)) { unsigned char out[1024]; size_t outlen = sizeof(out); if (EVP_PKEY_derive_init(pctx) <= 0 || EVP_PKEY_CTX_set_hkdf_md(pctx, EVP_sha256()) <= 0 || EVP_PKEY_CTX_set1_hkdf_salt(pctx, "salt", 4) <= 0 || EVP_PKEY_CTX_set1_hkdf_key(pctx, "secret", 6) <= 0 || EVP_PKEY_CTX_add1_hkdf_info(pctx, "label", 5) <= 0 ) { ERR_error_string(ERR_get_error(), error); printf("%s\n", error); } else { int r = EVP_PKEY_derive(pctx, NULL, &outlen); if (r <= 0) { ERR_error_string(ERR_get_error(), error); printf("EVP_PKEY_derive: %d, %s\n", r, error); } else { printf("%d\n", outlen); } } EVP_PKEY_CTX_free(pctx); } return 0; }
运行输出
EVP_PKEY_derive: 0, error:00000000:lib(0):func(0):reason(0)
原因分析
- 输出长度限制触发返回0:HKDF默认输出长度上限为哈希函数的输出长度(SHA256对应32字节),你初始化的
outlen为1024字节,远超过该上限。调用EVP_PKEY_derive传入NULL缓冲区获取长度时,因超出限制返回0,但未正确写入错误栈,导致无有效错误信息。 - 错误栈未被填充:部分参数校验失败场景下,OpenSSL 1.1.1k可能不会生成对应的错误码,导致
ERR_get_error()返回空值。
解决方案
通过EVP_PKEY_CTX_set_hkdf_outlen明确设置合法的输出长度(不超过哈希长度×255,SHA256最大为8160字节),同时调用EVP_PKEY_derive时传入有效输出缓冲区。
修正后的代码
#include <openssl/err.h> #include <openssl/evp.h> #include <openssl/kdf.h> #include <stdio.h> int main() { char error[1024]; if (EVP_PKEY_CTX* pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL)) { unsigned char out[1024]; size_t outlen = sizeof(out); if (EVP_PKEY_derive_init(pctx) <= 0 || EVP_PKEY_CTX_set_hkdf_md(pctx, EVP_sha256()) <= 0 || EVP_PKEY_CTX_set1_hkdf_salt(pctx, "salt", 4) <= 0 || EVP_PKEY_CTX_set1_hkdf_key(pctx, "secret", 6) <= 0 || EVP_PKEY_CTX_add1_hkdf_info(pctx, "label", 5) <= 0 || // 设置输出长度为SHA256默认长度32字节,可按需调整(最大8160) EVP_PKEY_CTX_set_hkdf_outlen(pctx, 32) <= 0) { ERR_error_string(ERR_get_error(), error); printf("%s\n", error); } else { int r = EVP_PKEY_derive(pctx, out, &outlen); if (r <= 0) { ERR_error_string(ERR_get_error(), error); printf("EVP_PKEY_derive: %d, %s\n", r, error); } else { printf("输出长度: %zu\n", outlen); // 可选:打印导出的十六进制密钥 printf("导出密钥: "); for (size_t i = 0; i < outlen; i++) printf("%02x", out[i]); printf("\n"); } } EVP_PKEY_CTX_free(pctx); } return 0; }
补充说明
- 若需先获取输出长度再分配内存,可先调用
EVP_PKEY_CTX_set_hkdf_outlen设置目标长度,再传入NULL缓冲区调用EVP_PKEY_derive确认长度。 - 输出长度不可超过哈希算法输出长度的255倍,这是HKDF规范的硬性限制。
内容的提问来源于stack exchange,提问作者user180574
相关产品推荐
相关产品推荐

