密码学系列——MD5算法理解记录

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

密码学系列——MD5算法理解记录


前言

主要是为了快速回忆之前工作的一些记录,不至于完全忘记。因此此处不会有完整的代码展示,需要的话可以直接网上搜索,挺多的。

MD5算法和MD4算法比较接近,这里同样以上节的明文密码“123994”作为研究对象。

从网上下载HashCalc工具,打开后按照文本字符串格式123994输入数值框中,选中MD5加密,再点击计算,如下图所示。

在这里插入图片描述

MD5算法流程

(1)待加密信息处理
显而易见,我们要对一个字符串进行MD5计算,那么肯定要从这个字符串的处理入手。我们知道一个字符的长度是一个字节,即8位(bit)的长度。MD5对待加密的字符串的处理是将一个字符串分割成每512位为一个分组,形如N512+R,这里的R是余下的位数。这个R分为几种情况:
R=0时,需要补位,单补上一个512位的分组,因为还要加入最后64个位的字符串长度。
R<448时,则需要补位到448位,后面添加64位的字符串长度。
R>448时,除了补满这一分组外,还要再补上一个512位的分组后面添加64位的字符串长度。
补位的形式是先填充一个1,再接无数个0,直到补足512位。
(2)MD5的链接变量及基本操作
MD5有四个32位的被称作链接变量的整数参数,这是个参数我们定义为A、B、C、D其取值为:A=0x01234567,B=0x89abcdef,C=0xfedcba98,D=0x76543210。但考虑到内存数据存储大小端的问题我们将其赋值为:A=0x67452301,B=0xefcdab89,C=0x98badcfe,D=0x10325476。
同时MD5算法规定了四个非线性操作函数(&是与,|是或,~是非,^是异或):
F(X,Y,Z) =(X&Y)|((~X)&Z)
G(X,Y,Z) =(X&Z)|(Y&(~Z))
H(X,Y,Z) =XYZ
I(X,Y,Z)=Y^(X|(~Z))
这些函数是这样设计的:如果X、Y和Z的对应位是独立和均匀的,那么结果的每一位也应是独立和均匀的。
利用上面的四种操作,生成四个重要的计算函数。首先我们声明四个中间变量a,b,c,d,赋值:a = A, b = B, c = C, d = D。然后定义这四个计算函数为:
FF(a, b, c, d, M[j], s, ti)表示 a = b + ((a + F(b, c, d) + Mj + ti) <<< s)
GG(a, b, c, d, M[j], s, ti)表示 a = b + ((a + G(b, c, d) + Mj + ti) <<< s)
HH(a, b, c, d, M[j], s, ti)表示 a = b + ((a + H(b, c, d) + Mj + ti) <<< s)
II(a, b, c, d, M[j], s, ti)表示 a = b + ((a + I(b, c, d) + Mj + ti) <<< s)
其中M[j]表示消息的第j个子分组(从0到15),<<表示循环左移s,常数ti是4294967296
abs(sin(i))的整数部分,i取值从1到64,单位是弧度。
(3)循环计算
定义好上述的四个计算函数后,就可以实现MD5的真正循环计算了。这个循环的循环次数为512位分组的个数。每次循环执行64不计算,上述4个函数每个16次,具体直接看代码

不多说了,直接给出代码关键部分解释
部分C模型代码,方便快速回忆
套用之前NTHASH的模板直接改,这里是输入

    int tmpPwdLen = 0;
    for (int i = 0; pwd[i] != 0; ++i)
    {
        *tmpPwdPtr++ = pwd[i];
        tmpPwdLen += 1;
    }
    md5(tmpPwd, tmpPwdLen, ntlmhash);

MD5算法依次经过了
由16次FF函数,16次GG函数,16次HH函数,16次II函数

//FF、GG、HH、II宏定义
#define rotate_left(x,s) (((x) << s)|((x) >> (32-s)))

#define F(x,y,z)  (((x)&(y))|(~(x)&(z))) 
#define G(x,y,z)  (((x)&(z))|((y)&~(z))) 
#define H(x,y,z)  ((x)^(y)^(z)) 
#define I(x,y,z)  ((y)^((x)|~(z))) 

#define FF(A,X,Y,Z,M,s,K) (A)=rotate_left((F((X),(Y),(Z))+(M)+(K)+(A)),(s))+(X)
 
#define GG(A,X,Y,Z,M,s,K) (A)=rotate_left((G((X),(Y),(Z))+(M)+(K)+(A)),(s))+(X)

#define HH(A,X,Y,Z,M,s,K) (A)=rotate_left((H((X),(Y),(Z))+(M)+(K)+(A)),(s))+(X)

#define II(A,X,Y,Z,M,s,K) (A)=rotate_left((I((X),(Y),(Z))+(M)+(K)+(A)),(s))+(X)

初值:

		A=output[0];
		B=output[1];
		C=output[2];
		D=output[3];

终值:

		output[0]+=A;
		output[1]+=B;
		output[2]+=C;
		output[3]+=D;

在这里插入图片描述

同时为了方便FPGA实现,将C模型改造成:

	FF(A,B,C,D,md5Input[0],7,0xd76aa478);  
	FF(D,A,B,C,md5Input[1],12,0xe8c7b756);
	FF(C,D,A,B,md5Input[2],17,0x242070db);
	FF(B,C,D,A,md5Input[3],22,0xc1bdceee);

如下形式,这样

	A=output[0];
		B=output[1];
		C=output[2];
		D=output[3];

		A_in=output[0];
		B_in=output[1];
		C_in=output[2];
		D_in=output[3];



		A_out=A_in;
		B_out=B_in;
	    C_out=C_in;
		D_out=D_in;

		X_out = ((B_in&C_in)|((~B_in)&D_in));
		Y_out = md5Input[0] + 0xd76aa478 + A_in ;
		Z_out = B_in;

//1
		X_in = X_out;
		Y_in = Y_out;
		Z_in = Z_out;
		A_in = A_out;
		B_in = B_out;
		C_in = C_out;
		D_in = D_out;


		
		A_out = D_in;
		B_out = rotate_left((X_in+Y_in),7) + Z_in;
		D_out = C_in;
		C_out = B_in;

		X_out = (((rotate_left((X_in+Y_in),7) + Z_in)&B_in)|((~(rotate_left((X_in+Y_in),7) + Z_in))&C_in));
		Y_out = md5Input[1] + 0xe8c7b756 + D_in ;
		Z_out = rotate_left((X_in+Y_in),7) + Z_in;

//2

		A_in = A_out;
		B_in = B_out;
		C_in = C_out;
		D_in = D_out;
		X_in = X_out;
		Y_in = Y_out;
		Z_in = Z_out;

		temp = rotate_left((X_in+Y_in),12) + Z_in;//rotate_left(((((B_in)&(C_in))|(~(B_in)&(D_in))) + md5Input[1] + 0xe8c7b756 + A_in),12) + B_in;
		A_out = D_in;
		D_out = C_in;
		C_out = B_in;
		B_out = temp;



//3
		A_in = A_out;
		B_in = B_out;
		C_in = C_out;
		D_in = D_out;

		temp = rotate_left(((((B_in)&(C_in))|(~(B_in)&(D_in))) + md5Input[2] + 0x242070db + A_in),17) + B_in;
		A_out = D_in;
		D_out = C_in;
		C_out = B_in;
		B_out = temp;
//4
		A_in = A_out;
		B_in = B_out;
		C_in = C_out;
		D_in = D_out;


		temp = rotate_left(((((B_in)&(C_in))|(~(B_in)&(D_in))) + md5Input[3] + 0xc1bdceee + A_in),22) + B_in;
		A_out = D_in;
		D_out = C_in;
		C_out = B_in;
		B_out = temp;

//5

		A_in = A_out;
		B_in = B_out;
		C_in = C_out;
		D_in = D_out;


		A = A_out;
		B = B_out;
		C = C_out;
		D = D_out;

注意几点,
1、 因为FF和GG和HH和II是比较大的组合逻辑,因此将这三个函数均拆成X_in、Y_in、Z_in
2、 该算法并行化耗费大量的触发器资源,打拍要省着点;但不打拍组合逻辑又比较大可能会影响系统频率,因此需要做权衡和试验,确定最优方法

总结

MD5算法的流程是:
1、填充成制定格式的数据
2、进行4轮函数运算,每轮16次

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十年老鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值