字符串length()/size()返回值异常:AES解密函数开发中的加密字符串长度问题求助
这问题我之前踩过类似的坑,核心原因是二进制加密数据被当成文本字符串处理时的编码转换问题,咱们一步步理清楚:
为什么直接复制粘贴会得到错误长度?
你复制的"(��P�$Y���k>"本质是16个二进制字节,但这些字节里包含大量不符合UTF-8(或你当前编辑器/终端使用的文本编码)规则的无效字节。当你把这些二进制数据粘贴到代码里作为字符串字面量时,编辑器会自动把这些无效字节转换成替代字符(�)——每个�在UTF-8编码里通常占1-3个字节,原本16个原始字节就被转成了28个字符长度的字符串。这时候length()/size()统计的是字符数,不是原始的二进制字节数,自然就不对了。
为什么存文件再读就正常?
当你把原始二进制数据写入文件时(一定要用二进制模式打开文件,比如C++里的ios::binary、Python里的'wb'),数据会被原封不动地存储成16个字节。读取时同样用二进制模式,直接读取原始字节,不会做任何编码转换,所以size()返回的就是正确的原始字节数。
解决办法
1. 用十六进制字符串替代二进制字符串字面量
这是最稳妥的方案:把原始16字节的加密数据转换成32位的十六进制字符串(每个字节对应两位十六进制字符),然后在代码里用这个十六进制字符串传递参数。解密函数第一步先把十六进制字符串转回字节数组,再进行AES解密。
比如假设你的原始加密字节数组转成十六进制后是28AB50CD2459EF0123456789AB6B3E,调用解密函数时就传这个字符串:
decrypttest("28AB50CD2459EF0123456789AB6B3E", "01 03 05 07 09 0A 0C 0E 02 04 06 08 0B 0D 0F 00");
解密时先写个工具函数把十六进制字符串转成字节数组,再用这个数组做AES解密。
2. 直接用字节数组存储加密数据
如果必须在代码里嵌入加密数据,别用字符串类型,改用字节数组。比如在C++里:
unsigned char encrypted_data[] = {0x28, 0xAB, 0x50, 0xCD, 0x24, 0x59, 0xEF, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0x6B, 0x3E, 0xXX}; // 解密函数参数改成接收字节数组和长度 decrypttest(encrypted_data, sizeof(encrypted_data), key_str);
这样操作的是原始二进制字节,长度统计肯定正确。
3. 修正解密函数的参数类型
AES算法处理的是字节流,不是文本字符串。建议把解密函数的第一个参数从string改成字节数组(比如C++的unsigned char*、Java的byte[]),从根源上避免文本编码带来的问题。
内容的提问来源于stack exchange,提问作者liana

