C语言中OpenSSL BIGNUM大整数取模触发段错误求助
排查OpenSSL BN_mod触发Segmentation Fault的问题
段错误的直接原因
你调用BN_mod时传入的第四个参数为NULL,但该函数要求传入有效的BN_CTX上下文对象,用于存储计算过程中的临时数据。传入NULL会导致函数内部访问非法内存,直接触发段错误。
修复后的完整代码
添加BN_CTX的初始化、使用和释放逻辑:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <openssl/bn.h> int main() { unsigned char message[] = "hello world"; int length = strlen((char *)message); BIGNUM *bn = BN_new(); if (!bn) { fprintf(stderr, "Failed to create BIGNUM\n"); return 1; } BN_zero(bn); for (int i = 0; i < length; i++) { for(int j=0; j<8; j++){ if ((message[i] >> (7-j)) & 1) { BN_lshift(bn, bn, 1); BN_add_word(bn, 1); } else { BN_lshift(bn, bn, 1); } } } BIGNUM *modolus = BN_new(); if (!modolus) { fprintf(stderr, "Failed to create modolus BIGNUM\n"); BN_free(bn); return 1; } BN_set_word(modolus, 1024); // 初始化BN上下文 BN_CTX *ctx = BN_CTX_new(); if (!ctx) { fprintf(stderr, "Failed to create BN_CTX\n"); BN_free(bn); BN_free(modolus); return 1; } BN_mod(bn, bn, modolus, ctx); char *dec = BN_bn2dec(bn); if (dec) { printf("%s\n", dec); OPENSSL_free(dec); } // 释放所有资源 BN_CTX_free(ctx); BN_free(bn); BN_free(modolus); return 0; }
更高效的替代方案(无需大整数库)
因为1024 = 2^10,模2^n的结果等价于取二进制数的最后n位。对应到原字符串,只需要处理最后2个字节(16位),取其低10位即可,完全不需要使用OpenSSL的大整数库:
#include <stdio.h> #include <string.h> int main() { unsigned char message[] = "hello world"; int len = strlen((char*)message); unsigned int result = 0; // 取最后2个字节(不足2个则取全部) for (int i = (len >= 2) ? len - 2 : 0; i < len; i++) { result = (result << 8) | message[i]; } // 取低10位,等价于模1024 result &= 0x3FF; printf("%u\n", result); return 0; }
运行后会输出正确结果292(对应"hello world"最后10位二进制0100100100的十进制值)。
内容的提问来源于stack exchange,提问作者hah
相关产品推荐
相关产品推荐

