gcc编译OpenSSL HMAC接口代码时报HMAC_CTX_init未定义引用错误
报错原因
该报错由代码API误用、编译命令写法错误共同导致:
- 编译命令存在语法错误:原命令中
-I/usr/local/ssl/include,末尾多了多余的逗号,导致gcc无法正确识别自行安装的OpenSSL 1.0.2u头文件路径,实际编译时引用了系统自带的高版本OpenSSL(1.1.0及以上)的头文件与库。高版本OpenSSL已经移除了HMAC_CTX_init符号,因此触发未定义引用错误。 - 代码存在API版本混用问题:原代码同时混用了OpenSSL 1.0.2和1.1+两个不兼容版本的HMAC接口,1.0.2版本不存在
HMAC_CTX_free函数,1.1+版本不存在HMAC_CTX_init函数。 - 代码存在内存与传参错误:原代码定义的
HMAC_CTX *ctx是未初始化的野指针,传参时传入&ctx属于二级指针,不符合1.0.2版本API的参数要求;HMAC_Update调用时对数组名data额外取地址,类型不匹配;代码缺失必要的头文件引用。
解决方法
1. 修正编译命令
去掉-I参数后的多余逗号,调整链接选项顺序,正确命令如下:
gcc main.c -I/usr/local/ssl/include -L/usr/local/ssl/lib -lssl -lcrypto -o hmac_test
如果运行时提示找不到libcrypto或libssl库,可执行前设置环境变量:
export LD_LIBRARY_PATH=/usr/local/ssl/lib:$LD_LIBRARY_PATH
2. 修正代码适配OpenSSL 1.0.2u版本
OpenSSL 1.0.2版本中HMAC_CTX是公开结构体,支持栈上直接分配,不需要手动为上下文申请内存;初始化用HMAC_CTX_init,清理用HMAC_CTX_cleanup,不要使用1.1+版本专属的HMAC_CTX_new/HMAC_CTX_free接口。修正后的完整可运行代码如下:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <openssl/hmac.h> #include <openssl/evp.h> int main() { // HMAC密钥 const char key[] = "012345678"; // 待计算认证码的原始数据 char data[] = "hello world"; // SHA1算法输出固定20字节 unsigned char* result; unsigned int len = 20; result = (unsigned char*)malloc(sizeof(unsigned char) * len); // 栈上直接分配HMAC上下文,1.0.2版本不需要手动malloc该结构体 HMAC_CTX ctx; HMAC_CTX_init(&ctx); // 传入密钥、指定哈希算法为SHA1,可替换为EVP_md5()/EVP_sha256()/EVP_sha512()等 HMAC_Init_ex(&ctx, key, strlen(key), EVP_sha1(), NULL); // 传入待哈希数据,数组名本身就是首地址,不需要额外取地址 HMAC_Update(&ctx, (unsigned char*)data, strlen(data)); HMAC_Final(&ctx, result, &len); // 清理上下文资源,1.0.2版本对应接口为HMAC_CTX_cleanup HMAC_CTX_cleanup(&ctx); printf("HMAC digest: "); for (int i = 0; i != len; i++) printf("%02x", (unsigned int)result[i]); printf("\n"); free(result); return 0; }
内容的提问来源于stack exchange,提问作者Kusai Mansawala
相关产品推荐
相关产品推荐

