加密签名不合法的分析过程及解决办法
一、出现场景
xxx平台关于能力调用过程中post请求出现签名不合法问题。表象如下图
二、日志分析
定位日志分析,我们发现密文在解密之后只获取到123个字节长度,而要求的是128个字节长度,初步分析密文存在字节丢失的可能性。进而对调用的入参存在问题提出异议。
三、验证分析
1、post请求使用get入参
目前的能力调用中,get请求正常,而post请求存在签名中参数不合法,此时我们把get入参作为能力调用的post请求入参,发现这样一个结果。如下图
图中,我们发现这时isTrueSign为true,说明参数通过校验管控,不在出现签名不合法的问题。
由此可认定post请求入参在加密之后存在问题。
2、源码分析
查找能力调用的入口,我们发现get和post请求在签名处理上存在是否有URLEncoder.encode(sign, "utf-8")的操作。如下图
3、网上资源分析
网络资源中提到对于post请求,签名存在的特殊字符如要做如下处理,xHttp.post(szURL, java.net.URLEncoder.encoder(“crackren+001”, “UTF-8”));即要注意字符的编码问题,否则会导致个别特殊字符被替换导致签名发生变化。如下图
https://blog.csdn.net/iteye_19297/article/details/82546042
4、get和post请求的签名比较
Get请求的签名:
sign=pf%2ByhVu7VH%2F3fQpkfbWkI5pJbHiAqXDOByGpCLtXyi%2Fbl2XI7Z3vka6YgnGGazv5Dlnot4df%2F0%2BKcGLBCyD9aP3%2BsULP6biV1WFLMNhBRUOKpUQCxtlRnskEXo5Q3Fmv%2FbleIx9USGlcxBPcyP%2FrEL5qvybb%2FFma1G9D5j1jrHw%3D
Post请求的签名:
sign=DH42/t/378DFMJumMOfWDHSGI/3IM772LdqZX+hmR7eQPgmQofx/IE4sSDVBx2TDAqmxnoc3n5xVKXlToOCvzjrlWgSXZbwP+6clVHN2dsOfarOJYrbBoV7BQmHR/ySXTryZogzJHHwLi1W8UWXFTSGwJfomBUKY5B4njyV+Od0=
观察get和post请求签名内容,我们发现post请求的签名中有”+”这样的特殊字符,如上述分析,这样的字符如不做编码处理会存在丢失或被转义的现象。
5、再次测试
修改post请求的签名处理源码,做如下操作
处理后的入参:apiTest=true&timeStamp=20200730144719&content={"SYR":"xxx","SFZMHM":"340xxxxxxxxxxxxx"}&userName=wuxiudan&status=1&appKey=10001079&messageId=0c5f52ec85ca4bdf9837bd34d82aa18b&sign=TTZdesVuOIJ08JNQZYdd7CaJAj%2BKX%2BT0ON2P5diHIpVLTAQkLHCCbC9pZLDpmcJRl4cBAawft3hB6YCJgXKGpkB36EovPSBFPM5%2FToCQDTEUcEFfqgrQXdBwKa5dpo%2Byv9UJneoRjP2L2u%2FoOwDZ%2BwDu7HVH62fa%2FEoZeRDav8k%3D
发现签名sign中不在有”+” 这样的字符。
再次调用之后,结果如下图
至此问题已基本解决。
四、反思
使用加密工具给参数做加密处理时要保证签名内容在加密之后、解密之前内容完全一致,任务特殊字符的缺失都会导致解析失败、验签失败。
验证一个想法是否有效,可以控制变量来验证。正向验证、反向验证。