本文原创作者一个程序员的奋斗史,如需转载,请先征得作者本人同意。不同于网络博客中的各种文章,下面的所有描述均经过仔细测试,如有不合适的地方需要讨论或有源码需求,请私信联系。

来源
在软件开发数据加解密过程中,经常会遇到Base64编解码。刚好工作内容会涉及到将逆向人员直接反编译所得的Java代码用C++实现应用于产品,其中经常出现Base64编解码出现问题,自己实现的C++版本URLDecode出来的结果居然和逆向hook处结果不一致,到底是哪里出了问题呢?此时,我们要拿出打破砂锅问到底的精神开启探索之路。
原理
以下内容来源网络:
Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,常用于在URL、Cookie、网页中传输少量二进制数据,Base64就是一种基于64个可打印字符来表示二进制数据的方法。
具体转换规则如下:
- 1.将待转换的字符串每三个字节分为一组,每个字节占8bit,那么共有24个二进制位。
- 2.将上面的24个二进制位每6个一组,共分为4组。
- 3.在每组前面添加两个0,每组由6个变为8个二进制位,总共32个二进制位,即四个字节。
- 4.根据Base64编码对照表获得对应的值。
PS:Base64并不是一种加解密方法,请勿混为一谈
Java是如何实现的?
说再多理论不如实际动手,Java8之后, java.util.Base64工具类已经为我们封装好了所有所需要的东西。具体使用方法如下:

然而,我们的C++实现的URL编码的结果却如下图:

为何和我们使用C++实现的结果会有差异呢,难道是我们 祖传的代码库有问题?
寻找差异
通过肉眼对比C++和Java结果,我们可以很快速的发现差异就出在中间的 /和 _身上了。那到底哪个才是正确的呢?通过查阅文档,我们发现了URL Safe编码这一名词,具体说法:
标准的Base64编码后可能出现字符+和/,在URL中就不能直接作为参数,所以又有一种"url safe"的Base64编码,其实就是把字符+和/分别变成-和_。
解决之道
既然我们已经知道了差异在哪,那剩下的部分就很easy来完成了,一个简单的字符串替换即可。
boost::replace_all(str, "/", "_");
boost::replace_all(str, "+", "-");
如需完整C++实现的URL Base64编解码实现函数,欢迎私信留言,我会在看到第一时间发送给你。
- END -
记得把公号加星标,会第一时间收到通知。
原创不易,如果觉得有点用,麻烦动动小拇指点右下角“在看”或者转发,扩散给更多人知道,在此拜谢。