You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用OpenSSL在C语言中将unsigned char[]类型哈希值转换为BIGNUM时输出为0的问题排查及转换方法咨询

问题分析与解决

你遇到的问题根源在于对BN_hex2bn的参数理解有误:这个函数要求输入的是十六进制编码的ASCII字符串,但你传入的hash是二进制原始哈希数据(比如SHA-256哈希是32字节的二进制值),不是ASCII格式的十六进制字符串,所以函数无法正确解析,最终得到的BIGNUM自然是0。

最优解决方案:直接用BN_bin2bn转换

OpenSSL提供了专门的函数BN_bin2bn,可以直接将二进制数据转换为BIGNUM,完全不需要先转成十六进制字符串,这是最高效、最直接的方法,函数定义如下:

BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
  • s:二进制数据的指针(也就是你的hash数组)
  • len:二进制数据的长度(你的hash_size)
  • ret:要写入的BIGNUM指针(如果传NULL会自动创建新的BIGNUM)

修改后的代码片段:

BIGNUM *h;
h = BN_new();
unsigned char hash[EVP_MAX_MD_SIZE];
unsigned hash_size = EVP_MAX_MD_SIZE;
EVP_DigestFinal_ex(hash_ctx, hash, &hash_size);
EVP_MD_CTX_free(hash_ctx);

// 打印哈希值
for (unsigned n = 0; n < hash_size; n++) {
    printf("%02hhx", hash[n]);
}
printf("\n");

// 直接将二进制哈希转换为BIGNUM
BN_bin2bn(hash, hash_size, h);
BN_print(bio_out, h);

如果你坚持用BN_hex2bn的转换方法

如果一定要通过十六进制字符串中转,那需要先把二进制hash数组转换成对应的ASCII十六进制字符串,再传给BN_hex2bn。步骤如下:

  1. 分配足够的字符串空间:每个字节对应2个十六进制字符,所以字符串长度是hash_size * 2 + 1(+1是为了存储字符串终止符\0)
  2. 遍历二进制数组,将每个字节转换为两个十六进制字符
  3. 调用BN_hex2bn,之后记得释放字符串内存

示例代码:

// ... 前面的哈希计算代码不变 ...

// 转换二进制哈希为十六进制字符串
char *hex_str = malloc(hash_size * 2 + 1);
if (!hex_str) {
    // 处理内存分配失败
    BN_free(h);
    return -1;
}
for (unsigned n = 0; n < hash_size; n++) {
    sprintf(hex_str + n*2, "%02x", hash[n]);
}
hex_str[hash_size * 2] = '\0';

// 用十六进制字符串初始化BIGNUM
BN_hex2bn(&h, hex_str);
BN_print(bio_out, h);

// 别忘了释放字符串
free(hex_str);

注意:这种方法多了一次字符串转换的开销,性能不如直接用BN_bin2bn,所以更推荐第一种方案。

内容的提问来源于stack exchange,提问作者CipherX

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 17:59:08