吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1465|回复: 0
收起左侧

[C&C++ 转载] 从0到1加密算法--MD5 hash算法

[复制链接]
TongShuai 发表于 2020-12-28 22:27

md5

  1. 填充

在消息后面先填充一个1,再填充0,直到消息长度mod 512=448,之后再将消息长度的低64位填充到消息结尾

  1. 定义几个运算

F(x,y,z)=(x&y)|(~x&z)

G(x,y,z)=(x&z)|(y&~z)

H(x,y,z)=x^y^z

I(x,y,z)=y^(x|~z)

ROL32(x,i) 左移32位

填充后的消息以512为一个分组,每个分组可以分成16个32位子分组$W_j(0<j<15)$

FF(a,b,c,d,M_j,s,t_i): a=b+ROL32(a+(F(b,c,d)+M_j+t_i),s)

GG(a,b,c,d,M_j,s,t_i): a=b+ROL32(a+(G(b,c,d)+M_j+t_i),s)

HH(a,b,c,d,M_j,s,t_i): a=b+ROL32(a+(H(b,c,d)+M_j+t_i),s)

II(a,b,c,d,M_j,s,t_i): a=b+ROL32(a+(I(b,c,d)+M_j+t_i),s)

  1. 定义初始化向量

A=0x01234567

B=0x89abcdef

C=0xfedcba98

D=0x76543210

  1. 对于每一个分组,将上一次计算的A,B,C,D复制到a,b,c,d中,进行下面的4轮计算,然后将a,b,c,d分别加到A,B,C,D上,下一组继续运行此算法,最终输出就是A||B||C||D,||在这里代表拼接
# 第一轮
for i in range(0,16,4):
    FF(a,b,c,d,M[pos[0][i]],s[0][0],t[0][i])
    FF(d,a,b,c,M[pos[0][i+1]],s[0][1],t[0][i+1])
    FF(d,a,b,c,M[pos[0][i+2]],s[0][2],t[0][i+2])
    FF(d,a,b,c,M[pos[0][i+3]],s[0][3],t[0][i+3])
# 第二轮
for i in range(0,16,4):
    GG(a,b,c,d,M[pos[0][i]],s[0][0],t[0][i])
    GG(d,a,b,c,M[pos[0][i+1]],s[0][1],t[0][i+1])
    GG(d,a,b,c,M[pos[0][i+2]],s[0][2],t[0][i+2])
    GG(d,a,b,c,M[pos[0][i+3]],s[0][3],t[0][i+3])
# 第三轮
for i in range(0,16,4):
    HH(a,b,c,d,M[pos[0][i]],s[0][0],t[0][i])
    HH(d,a,b,c,M[pos[0][i+1]],s[0][1],t[0][i+1])
    HH(d,a,b,c,M[pos[0][i+2]],s[0][2],t[0][i+2])
    HH(d,a,b,c,M[pos[0][i+3]],s[0][3],t[0][i+3])
# 第四轮
for i in range(0,16,4):
    II(a,b,c,d,M[pos[0][i]],s[0][0],t[0][i])
    II(d,a,b,c,M[pos[0][i+1]],s[0][1],t[0][i+1])
    II(d,a,b,c,M[pos[0][i+2]],s[0][2],t[0][i+2])
    II(d,a,b,c,M[pos[0][i+3]],s[0][3],t[0][i+3])

其中pos和t,s数组会在代码中体现

#include <stdio.h>
#include <memory.h>
#include <string.h>
#include <inttypes.h>
#include <stdlib.h>

#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 ROL32(x,i) (((x)<<(i))|((x)>>(32-(i))))
#define FF(a,b,c,d,M_j,s,t_i) ((b)+ROL32((a)+(F(b,c,d)+(M_j)+(t_i)),s))
#define GG(a,b,c,d,M_j,s,t_i) ((b)+ROL32((a)+(G(b,c,d)+(M_j)+(t_i)),s))
#define HH(a,b,c,d,M_j,s,t_i) ((b)+ROL32((a)+(H(b,c,d)+(M_j)+(t_i)),s))
#define II(a,b,c,d,M_j,s,t_i) ((b)+ROL32((a)+(I(b,c,d)+(M_j)+(t_i)),s))

uint8_t s[] = {
    7,12,17,22,
    5,9,14,20,
    4,11,16,23,
    6,10,15,21
};
uint32_t t[] = {
    0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,
    0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,
    0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be,
    0x6b901122,0xfd987193,0xa679438e,0x49b40821,

    0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa,
    0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,
    0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,
    0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a,

    0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c,
    0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70,
    0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,
    0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,

    0xf4292244,0x432aff97,0xab9423a7,0xfc93a039,
    0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1,
    0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1,
    0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391
};
void printArray(char *name,uint8_t *data,size_t len){
    printf("===========%s==============\n",name);
    for(size_t i=0;i<len;i++){
        printf("%02x,",data[i]);
    }
    printf("\n");
}
void md5(uint8_t *data,size_t len,uint32_t res[4]){
    uint32_t iv[4] = {0x67452301,0xefcdab89,0x98badcfe,0x10325476};
    uint32_t a,b,c,d;
    size_t pos;
    // 消息填充
    size_t plen = ((len+1+63)>>5)<<5;
    uint8_t *pdata = alloca(plen);
    memcpy(pdata,data,len);
    pdata[len]=0x80;
    memset(&pdata[len+1],0,plen-len-1);
    memcpy(&pdata[plen-8],&plen,8);
    // printf("%lld\n",plen);
    // printArray("my",pdata,plen);
    // 进行计算

    for(size_t i=0;i<plen;i+=64){
        a = iv[0];
        b = iv[1];
        c = iv[2];
        d = iv[3];
        // printf("iv[%d]: %08x %08x %08x %08x\n",i/64,a,b,c,d);
        // 第一轮
        pos=0;
        for(size_t j=0;j<16;j+=4){
            a = FF(a,b,c,d,*(uint32_t*)&pdata[pos*4+i*64],s[0],t[j]);
            // printf("%08x %08x %08x %08x\n",a,b,c,d);
            pos+=1;
            d = FF(d,a,b,c,*(uint32_t*)&pdata[pos*4+i*64],s[1],t[j+1]);
            pos+=1;
            c = FF(c,d,a,b,*(uint32_t*)&pdata[pos*4+i*64],s[2],t[j+2]);
            pos+=1;
            b = FF(b,c,d,a,*(uint32_t*)&pdata[pos*4+i*64],s[3],t[j+3]);
            pos+=1;
        }
        // 第二轮
        pos=1;
        for(size_t j=0;j<16;j+=4){
            a = GG(a,b,c,d,*(uint32_t*)&pdata[pos*4+i*64],s[4],t[16+j]);
            pos=(pos+5)&0xf;
            d = GG(d,a,b,c,*(uint32_t*)&pdata[pos*4+i*64],s[5],t[16+j+1]);
            pos=(pos+5)&0xf;
            c = GG(c,d,a,b,*(uint32_t*)&pdata[pos*4+i*64],s[6],t[16+j+2]);
            pos=(pos+5)&0xf;
            b = GG(b,c,d,a,*(uint32_t*)&pdata[pos*4+i*64],s[7],t[16+j+3]);
            pos=(pos+5)&0xf;
        }
        // 第三轮
        pos=5;
        for(size_t j=0;j<16;j+=4){
            a = HH(a,b,c,d,*(uint32_t*)&pdata[pos*4+i*64],s[8],t[32+j]);
            pos=(pos+3)&0xf;
            d = HH(d,a,b,c,*(uint32_t*)&pdata[pos*4+i*64],s[9],t[32+j+1]);
            pos=(pos+3)&0xf;
            c = HH(c,d,a,b,*(uint32_t*)&pdata[pos*4+i*64],s[10],t[32+j+2]);
            pos=(pos+3)&0xf;
            b = HH(b,c,d,a,*(uint32_t*)&pdata[pos*4+i*64],s[11],t[32+j+3]);
            pos=(pos+3)&0xf;
            printf("%08x %08x %08x %08x\n",a,b,c,d);
        }
        // 第四轮
        pos=0;
        for(size_t j=0;j<16;j+=4){
            a = II(a,b,c,d,*(uint32_t*)&pdata[pos*4+i*64],s[12],t[48+j]);
            pos=(pos+7)&0xf;
            d = II(d,a,b,c,*(uint32_t*)&pdata[pos*4+i*64],s[13],t[48+j+1]);
            pos=(pos+7)&0xf;
            c = II(c,d,a,b,*(uint32_t*)&pdata[pos*4+i*64],s[14],t[48+j+2]);
            pos=(pos+7)&0xf;
            b = II(b,c,d,a,*(uint32_t*)&pdata[pos*4+i*64],s[15],t[48+j+3]);
            pos=(pos+7)&0xf;
        }
        iv[0]+=a;
        iv[1]+=b;
        iv[2]+=c;
        iv[3]+=d;
    }
    memcpy(res,iv,sizeof(uint32_t)*4);
}

int main(){
    uint32_t res[4];
    md5("deadbeef",8,res);
    printArray("mymd5",(uint8_t*)res,16);
    return 0;
}
参考资料

《应用密码学:协议、算法与C源程序》

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 22:42

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表