C语言用OpenSSL EVP做AES-128-CBC加密转十六进制串多余f问题咨询
问题根因
你遇到的多余f前缀是C语言的有符号字符整型提升导致的:
- 大部分编译器默认
char类型为带符号的signed char,取值范围是-128 ~ 127 - 当加密字节的数值大于
0x7F(即十进制127)时,会被识别为负数 printf的%x格式符默认按unsigned int处理参数,负数做整型提升时会补符号位,就出现了前缀的ffffff- 同时你用的
%x不会补前导0,所以0x00会输出为0而非预期的00
修复现有循环代码的方案
只需要修改printf语句,做两个调整即可:
- 将字节强制转为
unsigned char消除符号位 - 用
%02hhx格式符:02表示不足两位补前导0,hh表示参数是单字节长度
修改后代码:
int i; for (i = 0; i < ciphertext_len; i ++) { printf("%02hhx", (unsigned char)newCipher[i]); } printf("\n");
该方案兼容性最好,不需要依赖额外库函数,适配所有OpenSSL版本。
OpenSSL原生规范方案
如果你已经在使用OpenSSL库,可以直接调用内置接口实现二进制转十六进制,不需要手动写循环,容错性更高:
方法1:OPENSSL_buf2hexstr直接生成十六进制串(适配OpenSSL 1.1.1及以上版本)
// 第三个参数为分隔符,传'\0'就会生成连续无间隔的十六进制串 char *hex_str = OPENSSL_buf2hexstr(newCipher, ciphertext_len, '\0'); printf("%s\n", hex_str); // 生成的字符串需要手动释放 OPENSSL_free(hex_str);
方法2:用BIO接口输出十六进制
和你之前使用的BIO_dump_fp同属BIO体系,适合生产环境使用:
BIO *bio = BIO_new(BIO_s_mem()); // 输出连续无换行的十六进制 BIO_hex_string(bio, 0, ciphertext_len, newCipher, ciphertext_len); BUF_MEM *buf; BIO_get_mem_ptr(bio, &buf); printf("%.*s\n", (int)buf->length, buf->data); BIO_free(bio);
内容的提问来源于stack exchange,提问作者FlaskDev
相关产品推荐
相关产品推荐

