MD5加密算法
在安卓逆向的过程中,对加密算法有足够的了解是必要的,下面将以"password"这个字符串为例,将演示他的加密过程
原始数据准备
字符串: password
二进制: 01110000 01100001 01110011 01110011 01110111 01101111 01110010 01100100
十六进制: 70 61 73 73 77 6F 72 64
长度 8 字节=64 位
完整的 MD5 计算过程
填充消息
1.当输入的字节数小于 56 个字节的时候,对其正常填充
原始长度是 64 位
填充规则:先补一个 1,即 1000 0000,换成 16 进制就是 0x80,再补 0 直到长度 448
计算填充:
- 64+1+k=448(mod 512)
- 65+k=448
- k=383
所以说需要填充 383 个 0
最后 64 位填充长度即0x0000000000000040
完整的填充就是下面这个样子:
2.当输入等于 56 个字节的时候,直接填充长度,不填充 80
3.当输入大于 56 字节,小于 64 字节的时候,此时已经没法填充长度了,例如:输入是 60 个字节,先填充 0x80,接着填充 0x0 填充到 64 字节,接着在新的 512 位的块中,先填充 0x80,然后一直填充 0x0,直到满足 56(mod 64),左后 8 个字节填充长度
4.当输入大于 64 字节的时候,比如:输入是 100 个字节,前 64 字节正常数据块,后 64 字节的前 36 字节填充剩余字节数据,然后一直填充 0,最后 8 字节填充长度
分组
| |
初始化常量
这个是 Md5 算法中第一个关键点:初始化常量,这些参数以小端字节序表示,会参与到后续的运算中,也会影响到最终的结果
最简单的魔改 md5 算法,就是魔改这里的模数
处理分组数据
在前面完成了对数据的填充分组,接下来开始进行运算了,默认的初始变量有 a,b,c,d 四个变量,会以第三步得到的初始化常量值对其进行赋值
之后进行 4 轮循环运算,每轮循环运算进行 16 次运算,分别对应一个非线性函数,以及分组,常量等,每次运算都会得到 a,b,c,d 的值,然后作为新值进行替换,最后经过四轮这样的运算,得到新的 a,b,c,d 的值,然后与初始化常量进行相加,最后将 a,b,c,d 的值进行拼接起来,得到最终的 md5 值
接着就引出了 md5 算法中的第二个关键点:非线性函数
每一轮都会使用到其中的一个线性函数进行运算,因此,非线性函数也就影响到了最终的结果,常常魔改算法,也会魔改这个地方
| |
接着看一下主要的 64 次运算
| |
在这个流程中,会用到 T 常量表,他的值也会影响到算法结果,这里也是一个魔改点,这也是 md5 算法中第三个需要关注的点
| |
同时还有第四个关键点,常量转换,他也会参与到非线性函数中循环左移的函数运算中,同样是个魔改点
通过这 64 次初始化常量,T 常量表,常量转换,非线性函数,就得到了新的 a,b,c,d 值
与初始化常量进行相加,就得到了最终的结果
算法代码实现
以下是算法的 C 语言实现
| |
常见的算法魔改点
- 初始化常量
- 非线性函数
- T 常量表
- 常量转换