先介绍下MD4算法然后再看NTLM
目录
MD4
补位
补的内容:首先是一个1,其余都是0
补的数量:使得补后的比特长度和 448 模512同余。
剩下的64比特:再补上之前输入串的比特流长度放入剩下的64比特中。
至此补位后的比特长度恰好能够分成若干组,每组的比特流都是512比特。
512比特经历了什么
上面以512比特为一组,分好后,就可以进行相关运算了。
512=32*16
1.首先总体上是三大轮:
输入---->第一大轮---->第二大轮---->第三大轮---->输出
2.细节就是每大轮中又有16小轮:
每轮中X[k]就是上面512比特中的第几个32比特;一共16个32比特单元,16*32=512
涉及到的三个函数:
第一大轮:
第二大轮:
第三大轮:
3.关于输入:
上面小轮运算中我们会看到ABCD四个参数,这里单独拿出来说,需要注意一些问题。
涉及大小端序的问题,小端序就是:低字节放在内存低地址处,高字节放在内存高地址处。
比如0x12345678;假定内存从左到右是由低地址到高地址,那么在内存存放顺序:0x78 0x56 0x34 0x12
我们或许在书上看到,A=0x01234567,B=.......
这个所谓的幻数给出的其实是在内存中的顺序。因此,在编程中我们要注意调整其顺序:
A=0x67452301
B=0xefcdab89
C=0x98badcfe
D=0x10325476
上面四个值是上面大轮中的最初输入。
然后每次经过一次大轮,ABCD会改变,改变后的ABCD又作为下一大轮的输入,然后三次大轮结束后,又做一下下面的运算:
AA/BB/CC/DD是三次大轮执行之前的ABCD的副本,就是为了在最后做这个运算
A=AA+A
B=BB+B
C=CC+C
D=DD+D
至此,一组512比特执行结束,也是输出ABCD。如果后面还有分组,那么输出的ABCD作为下一组的参数输入,直至全部结束,最终得到的ABCD组合起来就是我们的Hash值。
因为四个参数,每个都是32位,所以输出固定是128比特,而输入不限。
4.关于输出
上面也谈到端序的问题。我们用的小端序,在输出我们的Hash时要注意,如果用printf函数进行输出一个32位整数时,要注意进行调整端序问题。
如果是以字符指针的形式从低地址依次取得存放数组中,然后依次输出每个数组元素,就不用改变其顺序,自己注意一下即可。
NTLM
这是windows口令验证的其中的一个东西
分:
1.将输入串进行Unicode编码,因为最初微软只小端序,所以编码时,直接在原来每个字节后面补一个字节0就行,换成2字节整数就是0在高位了。
2.将编码后的比特流作为MD4的输入,直接进行补位操作,最后求得的哈希值就是相应的NTLM值。
留言
代码已经实现,后面会进行上传。