Base64 空格,加号问题

缘由:

在一个项目中,app请求tcpdump日志与记录的日志内容不一致

请求%2B 识别成 +

请求 + 识别成 空格

这个在base64解密的时候会出现异常,base64需要的是加号,而不是空格

造成的原因:

在js中,对url的加密分别由三种方式:

escape("aa+aa aa")
"aa+aa%20aa"

encodeURI("aa+aa aa")
"aa+aa%20aa"

encodeURIComponent("aa+aa aa")
"aa%2Baa%20aa"

第三种方式,+变成%2B

java代码:

System.out.println(URLEncoder.encode("aa+aa aa","UTF-8"));
aa%2Baa+aa

特么加号变成%2B,空格变成加号

如果是没经过加密,但是解密了

System.out.println(URLDecoder.decode("aa+aa aa","UTF-8"));
aa aa aa

好吧,从这里就可以看出,为什么base64解密报错了

app端进行base64加密,内部含有+,然后并没有进行url加密,直接传给后端,后端对其先进行Url解密,+变成了空格,再进行base64解密,所以报错。

规范:

造成这种混乱局面的原因在于:

W3C标准规定,当Content-Type为application/x-www-form-urlencoded时,URL中查询参数名和参数值中空格要用加号+替代,所以几乎所有使用该规范的浏览器在表单提交后,URL查询参数中空格都会被编成加号+。

而在另一份规范(RFC 2396,定义URI)里, URI里的保留字符都需转义成%HH格式(Section 3.4 Query Component),因此空格会被编码成%20,加号+本身也作为保留字而被编成%2B,对于某些遵循RFC 2396标准的应用来说,它可能不接受查询字符串中出现加号+,认为它是非法字符。所以一个安全的举措是URL中统一使用%20来编码空格字符。

Java中的URLEncoder本意是用来把字符串编码成application/x-www-form-urlencoded MIME格式字符串,也就是说仅仅适用于URL中的查询字符串部分,但是URLEncoder经常被用来对URL的其他部分编码,它的encode方法会把空格编成加号+,与之对应的是,URLDecoder的decode方法会把加号+和%20都解码为空格,这种违反直觉的做法造成了当初我对空格URL编码问题的困扰。

因此后来我的做法都是,在调用URLEncoder.encode对URL进行编码后(所有加号+已被编码成%2B),再调用replaceAll(“+”, “%20″),将所有加号+替换为%20。

参考:

[故障引起的故事]URL中带加号的处理

字符解码时加号解码为空格问题探究

URL中关于空格的编码转换成+或转换成%20的问题

posted @   hongdada  阅读(13700)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
历史上的今天:
2013-01-30 List<T> DataSet 转换
点击右上角即可分享
微信分享提示