OpenSSL BN_hex2bn与BN_bn2hex转换异常:无法还原原十六进制串
解决OpenSSL BN_hex2bn/BN_bn2hex转换后字符串变长的问题
你的问题我很熟悉——明明是把十六进制串转成BIGNUM再转回字符串,结果却多出一串莫名其妙的后缀,这大概率是代码用法疏漏或者编译链接错误导致的,下面一步步帮你排查解决:
1. 修正BN_hex2bn的调用细节
你先调用BN_new()创建BIGNUM再传给BN_hex2bn的思路没问题,但漏了两个关键步骤:
- 初始化BIGNUM:
BN_new()创建的对象是未初始化的,虽然BN_hex2bn会覆盖原有数据,但为了避免垃圾数据干扰,最好先调用BN_zero(test2)把它初始化为0:BIGNUM* test2 = BN_new(); if (!test2) { fprintf(stderr, "BN_new 创建失败\n"); return 1; } BN_zero(test2); // 初始化BIGNUM为0 - 检查解析返回值:
BN_hex2bn的返回值是成功解析的字符数,返回-1说明解析失败,此时test2里是无效数据,后续BN_bn2hex自然会输出垃圾内容:int parsed_len = BN_hex2bn(&test2, argv[1]); if (parsed_len == -1) { fprintf(stderr, "解析十六进制串失败\n"); BN_free(test2); return 1; } // 额外验证:确保解析长度和输入字符串长度一致,避免意外截断 if (parsed_len != strlen(argv[1])) { fprintf(stderr, "警告:只解析了%d个字符,输入总长度是%zu\n", parsed_len, strlen(argv[1])); }
2. 必须正确链接OpenSSL库
这是新手最容易踩的坑:如果编译时没有链接OpenSSL的crypto库,编译器会错误推断函数的参数和返回值类型,导致函数调用行为完全异常,出现各种奇怪的输出。
正确的编译命令应该是这样的:
gcc your_code.c -o a.out -lcrypto
千万别只写gcc your_code.c——有些环境可能不会直接报错,但运行时的行为完全不可预测,你遇到的长后缀问题很可能就是这个原因。
3. 养成释放内存的好习惯
虽然这不会直接解决当前问题,但能避免后续的内存泄漏:
- 用完BIGNUM后调用
BN_free(test2) - 用完
BN_bn2hex返回的字符串后调用OPENSSL_free(number_str_test2)
修改后的完整代码示例
#include <stdio.h> #include <string.h> #include <openssl/bn.h> int main(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "用法:%s <十六进制串>\n", argv[0]); return 1; } BIGNUM* test2 = BN_new(); if (!test2) { fprintf(stderr, "创建BIGNUM失败\n"); return 1; } BN_zero(test2); int parsed_len = BN_hex2bn(&test2, argv[1]); if (parsed_len == -1) { fprintf(stderr, "解析十六进制串失败\n"); BN_free(test2); return 1; } if (parsed_len != strlen(argv[1])) { fprintf(stderr, "警告:解析了%d个字符,输入总长度是%zu\n", parsed_len, strlen(argv[1])); } char *number_str_test2 = BN_bn2hex(test2); if (!number_str_test2) { fprintf(stderr, "BN_bn2hex转换失败\n"); BN_free(test2); return 1; } printf("转换后的十六进制串:%s\n", number_str_test2); // 释放资源 OPENSSL_free(number_str_test2); BN_free(test2); return 0; }
为什么会出现长后缀?
按照上面的步骤修改后,应该就能得到和原输入一致的结果了。之前的问题大概率是这两个原因:
- 编译时没加
-lcrypto,导致BN_hex2bn调用异常,把内存里的垃圾数据解析进了BIGNUM - 没检查
BN_hex2bn的返回值,解析失败后依然用无效的BIGNUM调用BN_bn2hex,输出了垃圾内容
内容的提问来源于stack exchange,提问作者user1470393
相关产品推荐
相关产品推荐

