上一节课我们介绍说——加解密是App逆向分析,Js逆向中都十分重要和不可或缺的一部分,所以我们有必要从一个整体的、俯视的角度去了解Android中的加解密算法。这节课我们来具体的验证和学习它。我们讲解的第一个加解密算法是MD5算法。
MD5消息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。
上面这是比较正式和官方的解释,我们使用更加通俗、实用、具体的语言来描述它。
MD5是一种散列函数,散列函数又译做哈希函数(Hash),很多人习惯称之为MD5加密算法,但实际上MD5是一种散列算法。
加密算法分为单向加密和双向加密,MD5是单向加密,比如123456的MD5值是e10adc3949ba59abbe56e057f20f883e,在理论上,没有办法可以从MD5值e10adc3949ba59abbe56e057f20f883e倒推到123456。而在双向加密算法中,加密的结果可以使用密钥和算法将加密以后的密文解密为原文,而MD5不行。MD5是单向加密这一点很关键,我们后续会再提到它。
对源数据进行最小的改变,MD5的结果变动都会非常大,值会完全不同。与此同时,只要明文不变,无论计算多少遍,MD5值都完全相同。而有一些加密算法,明文相同,加密结果可能有许多种。
MD5在Android中常用来用作sign签名:比如账号注册/登录时,计算密码的MD5值,传输时使用密码的MD5值;比如POST data中,常常就是对其他所有POST的字段进行拼接,之后求MD5值,只要你一个字段值不对,这个md5值就不可能正确,这样就很好的达到了防护和验证的目的。这个签名字段有时候叫sign,也有时候直接用原意signature(签名)。
下面是几个JS和Android中的例子
上面我们讲了什么是MD5,那么我们为什么需要了解MD5????
从上文我们可以知道MD5最明显的两个特征是32位和不可逆
如何利用这两个特征?
我们就可以在抓包和JS解密时,一看到32位的字符串,且只有0-9+a-f这十六个字符出现,就立马意识到这是一个MD5,然后针对MD5加密的特征进行突破,而不是毫无底气的乱找!
属于何种加密这个信息本身,就可以提供大量的信息。
比如在Android开发中中,MD5加密的实现代码往往是类似的,所以我们可以针对其中必须要使用的方法、函数和流程,进行Hook(后续会讲),这样就可以得到程序中加密前的原文和堆栈调用。
而在Js解密中,如果我们确定某个参数是MD5加密,但我们始终找不到这个参数生成的具体逻辑,那么我们也可以直接全局搜索MD5函数,直接在实现MD5的Javascript函数上打断点。
我们先来想一下服务器的美梦,将许多个字段拼接join在一起,然后轻轻松松求个MD5,根据我们上面讲的第三点,MD5原文只要发生微小变化,MD5的结果就会完全不同。
那么如果请求字段中加上sign,当你想通过爬虫程序大规模模拟请求数据时,只要有一个字段没搞清楚,或者一个字段没有解密出来,sign的MD5就必定是错的,服务器验证不通过,资源不予请求,多么爽歪歪。
MD5是不可逆的,那么我们就需要考虑——服务器它自己拿到了MD5值,却也没办法还原成原文,来查看和比对每个字段的内容,那怎么验证你提交的字段是对是错??
所以呀,服务器没办法逆向MD5的结果,它只好拿一模一样的原数据做一遍MD5,校验结果。
那么首先,它需要将源数据和签名后的值一起提交到后台,保证服务器拥有原数据。比如通过一个很长的get请求,里面一堆杂七杂八的字段,加上一个sign字段,或者通过一个简单的post data。
其次,这里有一个问题,我们前面说,sign可能是对六七八九十个字段先进行拼接,然后进行MD5加密,得到一个结果,那么假设我们的字段如下?
“c=3&f=lilac&a=verison 3.3&d=timestamp&……&g=……&……”
怎么确定字段拼接的先后呢?
你把一堆东西塞进某个Java集合,万一集合自己对数据进行了个啥排序,或者某个字段用户没提交/不需要提交时,那不就全乱套了吗?怎么保证你在本地的加密顺序和服务器端加密顺序是一致的呢?
在Android开发中,通常使用的处理办法是先对字段进行排序。
比如说,把需要参与MD5加密的字段的字段名,单独拎出来搞个数组,弄一下array.sort排序,然后再通过字典取值的方式拼接出排序后的key value值进行MD5.
处理前:“c=3&f=lilac&a=verison 3.3&b=timestamp&……&g=……&……”
处理后:“a=version3.3&b=timestamp&c=3&……”
正因为在Android的客户端和服务器中都做了这样的处理,因此排序不会出现问题了。
那么当我们反编译源码时,几千几万行代码中,就需要有意识的看这样的代码结构,一眼看到一个map集合,下面对它进行了sort排序,稳了稳了,十有八九是你要找的MD5.
到此为止吧,这一篇blog。
现在是凌晨一点半,blog是从10点开始写的,我现在关心这样几件事:
参考和借鉴的BLOG
https://blog.csdn.net/qq_30993595/article/details/80453807
https://blog.csdn.net/baidu_34045013/article/details/80687557
接下来几个小节的内容才是实践和重点,大家加油!