很多时候我只是优秀工具的使用者,优秀的工具用好了才能发挥作用
最近使用cryptopp的base64对压缩后的zip文件内容进行加密遇到了问题。
首先zip压缩没问题,可是最后得到的base64字符串不对:
1、长度不对(问题应该是源字符串的问题)
2、使用现成的工具解密得不到zip文件内容(问题没有头绪)
3、计算得出的MD5无效
既然没法从问题的表现来推理解决,那就从正常逻辑往后判断问题的根源点
1、先检查zip的读取,利用fread读出后再fwrite写入,以确定fread的内容是有效的
此过程中发现fwrite写入的zip文件异常,对比文件的十六进制数据后发现在每一个0x0A前面都多了一个0x0D,对比ascii码就知道是换行符的问题;
但fread不会有问题,一个意外收获,至此确定fread读出的内容没问题。
2、检查base64的输出内容,首先来看base64的调用代码:
string getBase64(const byte* src, const int len)
{
Base64Encoder encoder;
encoder.Put(src, len);
encoder.MessageEnd();
lword size = encoder.MaxRetrievable(); byte* encodestr = new byte[size + ];
encodestr[size] = '\0'; encoder.Get(encodestr, size); ostringstream osstr;
osstr << encodestr; delete []encodestr; return osstr.str();
}
上面代码能正常输出base64的加密结果,可是对这个结果进行md5得到的校验码无效。
3、md5经过上篇文章的使用已经确定是正确的,那就是base64的输出(md5的输入)有异常。
可能有人在步骤2中就感觉到了问题,也就是0XOD 0X0A。有跨平台开发经验的朋友会想到这个换行符会出问题。
4、base64编码后的数据依旧出现了0x0A(\n),把base64的输出字符串使用现成的工具进行md5,然后对比自己md5代码出来的结果发现异常。
5、此时应该反应到\n上,如果字符串需要输出\n就需要这样表示"\\n",也就是转义字符,至此问题找到。2次md5的输入不一样自然不一样,那么在代码里面的字符串使用"\\n"测试,md5结果就能对上了.
6、问题找到了就要找解决办法了,最直接的办法,对base64的输出进行替换,"\n"替换成"\\n",到此似乎问题就解决了,可是这样的办法总是不尽人意。
7、为什么在base64加密后会产生0x0A了,首先想到是输入的引入,可是对比0x0A的数量后断定不是输入引入,此时把base64的输入放入记事本会发现0x0A的位置相当固定,莫非是base64增加的?
8、因为是第一次使用base64,经验自然就没用,那就度娘,google同时来,直接搜索“base64 转义字符”。
9、搜索结果表明:base64加密默认会在固定长度位置加入换行符(0x0A)。那剩下就是看看cryptopp的base64如何更改这个默认设置,让其不加入换行符了,看了cryptopp的base64.h文件后修改代码如下即可。
Base64Encoder encoder(nullptr, false);
10、至此问题解决,base64的加密使用也算初步了解。深入原理研究待以后需要再进行,毕竟项目时间不允许。