很多時候我只是優秀工具的使用者,優秀的工具用好了才能發揮作用
最近使用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 + 1]; 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的加密使用也算初步了解。深入原理研究待以后需要再進行,畢竟項目時間不允許。