加号与空格的故事

    近期给客户发了一些调研的邮件,希望能借由邮件了解用户对于网站一些重要功能的需求,后续还会对部分用户进行进一步的调研,纠结的是该调研系统是外部系统,如果我们需要将调研结果精确到人的话就需要向它传递一个类似id的唯一标识,如果传递email或者用户id会涉及到数据泄露和法律问题,如果传递一串数字id,就需要对每封邮件生成id并记录下来,成本有点高,所以最终决定将用户标识加密传递给外部系统,第一次调研后我根据调研结果文件解密一切正常,只有一个数据没有解密成功,我也没太在意。第二次调研后,我被告知,该结果需要当天完成好向高层汇报让我赶紧弄出来,于是会没开完我就离席了,本想应该很轻松,但这次居然只解析出40%左右的数据,其他数据都不太正常,具体表现就是部分数据虽然解析出来,但是头尾会带乱码,或者就是完全乱码。

    理论上来说,如果在加密解密过程中出现问题,绝大多数的结果应该都是乱码,问题出现,首先回顾一下整个数据流转的过程

     1. 数据被edm系统加密,然后对url encoding(utf-8),最终邮件通过发送系统推送到用户邮箱

     2. 用户在客户端打开邮件,看到调研链接,点击链接,在客户机浏览器打开链接,访问到调研系统

     3. 调研系统解析到传递过来的唯一标识,保存并记录当前用户调研结果

     4. 调研结果导出到excel文件

     5. 将excel文件中加密的唯一标识写入txt文件,并读取,解密

先考虑最简单的情况,也就是第五步将excel中的唯一标识copy到txt文件的过程是否有额外字符的拷贝,或excel本身就加入了额外字符,经过排查,不是该原因,期间想通一件事,就是解析结果有40%的正确率是由于加密过程中撒了盐,所以间接证明了秘文并未完全失真,可能只有很少的部分信息是错误的导致有部分数据能够被解析出来,顺着这个思路继续想,把问题定位到第一步,url encoding部分,由于我们采用了utf-8作为encoding参数,而调研系统的decoding charset未知,所以是否由于两个字符集对于密文中部分字符的编码结果不一致导致呢,结果发现除了utf16会导致结果不一致以外(ascii不兼容字符集),其他字符集decode都没问题(都是ascii兼容字符集),于是我回过头仔细分析了第一次的调研结果和第二次的调研结果,悲情的发现,第二次的调研结果里唯一标识符居然出现了空格,而且第一次调研结果失败的那条记录里也有空格,考虑到加密结果是base64编码的基本模式,所以猜测应该将空格替换为那个该死的加号,解密终于成功了。。。。问题是,为啥会出现空格,对加密结果是做过url encoding的,加号会被替换为%2B,根据相关的协议,是不会反解析为空格的(http://www.w3.org/TR/html5/association-of-controls-and-forms.html#url-encoded-form-data),如果没有url encoding ,base64编码后可能会在url里出现加号,最后decoding的时候变成空格。。

    为啥正确的做法还是会有问题呢,问题出现在邮件客户端的可能性很小,因为客户的邮箱各式各样,更有可能的一种问题是double decoding造成,加号encoding一次,decoding两次变成了空格,杯具~查了很久都没注意到空格,要不应该可以很快恢复数据,现阶段很难猜测对方服务器为什么在近期出现double decoding问题,如果后续继续出现问题只能去联系对方问问看了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章