问题背景
有个文件数据上传功能,客户端上传文件内容时,会将文件内容base64并且附带上文件内容的md5,后端的逻辑是将这个base64解密后,再把内容md5,并对比客户端的md5是否一致,从而达到防止数据篡改的目的
问题描述
有极少数的用户反馈无法上传文件,排查日志发现是因为用户上传的文件md5校验没有通过,通过错误日志落地,发现落地的文件内容数据表现的有点奇怪,对应的base64数据+都被替换了空格,这是因为php在获参数时会自动url decode,服务端在在校验md5时会先把客户端传来的base64字符串空格替换成+,然后再解密,所有这个逻辑看着是挺正常的,但是拿用户数据来和客户端联调发现MD5还是不一致,经过一段折腾,最后发现是框架底层在获取客户端传参时自动参数进行两端去除空格处理,导致上传的base64最后一位为+号的文件数据,被剪掉了一位,从而base64 解密出来的数据和客户端上传的已经是不一致了
引出的问题
1.base64传参在php服务端获取时会自动url decode,把+转成空格,虽然可以手动转回去,但是感觉最正经的设计应该客户端在传参时先对这个传参 url encode一下
2.php内置函数在对少了最后一位的base64数据进行解密,居然是能解出内容的?而不是抛异常,查询的资料如下:
base64的编码原理
Base64编码通过将3个字节(共24位)的二进制数据转换成4个Base64字符来工作。每个Base64字符表示6位,因此24位被等分为4部分。这意味着在Base64编码中,每4个字符代表原始数据的3个字节。
“+” 字符在Base64中的角色
“+” 字符是Base64编码中使用的64个字符之一,用于表示特定的6位二进制序列。如果Base64编码的字符串以"+“结尾,这表示原始数据在转换为Base64字符时,最后的几位被”+"所代表。
为什么少了一个"+"字符还能正常解码
从Base64编码的字符串中移除最后一个字符(不管是"+"还是其他字符),实际上是在移除原始数据最后的6位(因为每个Base64字符代表6位二进制数据)。这意味着解码器在解码时会缺失某些数据,但由于Base64编码的最后4个字符代表原始数据的最后3个字节,而最后的几个字节通常用于对齐,因此在某些情况下,即使丢失了一些信息,解码器仍然可以恢复出大部分(如果不是全部)原始数据。