MD5及其底层原理

MD5是一种广泛使用的128位散列函数,由Ronald Linn Rivest设计。它将任意长度的输入转化为固定长度的输出,主要用于数据完整性验证。MD5算法主要包括填充原文、设置初始值、循环加工和密文拼接四个步骤。在循环加工阶段,通过F、G、H、I四个非线性函数进行多轮处理。尽管MD5存在安全性问题,但其原理仍然对理解哈希函数有所帮助。
摘要由CSDN通过智能技术生成

本文大部分摘自TOMORROW星辰:漫画趣解MD5算法

MD5是什么

MD5信息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。MD5由美国密码学家罗纳德·李维斯特(Ronald Linn Rivest)设计,于1992年公开,用以取代MD4算法。这套算法的程序在 RFC 1321 标准中被加以规范。1996年后该算法被证实存在弱点,可以被加以破解,对于需要高度安全性的数据,专家一般建议改用其他算法,如SHA-2。2004年,证实MD5算法无法防止碰撞(collision),因此不适用于安全性认证,如SSL公开密钥认证或是数字签名等用途。----百度百科

MD5可以将任意长度的输入串经过计算得到固定长度(128位)的输出,而且只有在明文相同的情况下,才能等到相同的密文,而且在很大程度上是不可逆的。

摘要哈希生成的正确姿势:

1.收集相关参数。

2.按照规则,把参数名和参数值拼接成一个字符串,同时把给定的密钥也拼接起来。之所以需要密钥,是因为攻击者也可能获知拼接规则。

3.利用MD5算法,从原文生成哈希值。MD5生成的哈希值是 128 位的二进制数,也就是 32 位的十六进制数。

MD5签名认证原理
请求方对请求数据按一定的规则排序,加上appkey码一起通过MD5加密生成签名,然后把请求数据和签名发给服务方,服务方拿到数据后,去掉appid和无用的数据,通过appid找到请求方的appkey,然后按同样的规则处理数据,并加上appkey通过MD5加密也生成签名,然后和请求方生成的签名去对比,如果值一样,签名验证通过。

需要的东西
服务商一般会给你一个appid,appkey;同时这两个参数服务商也会保存,这两个形成了你的唯一标识。 appid通过网络传输,而appkey是不在网络上进行传输的,只在生成签名时使用,所以安全性还是比较高的。

来自最详细的MD5签名的原理和流程

MD5算法底层原理

简单概括为4步:
处理原文、设置初始值、循环加工、密文拼接

  1. 处理原文
    在MD5算法中要对数据进行按位填充,要求最终的位数对512求模的结果为448。即便是这个数据的位数对512求模的结果正好是448也必须进行补位。至少补1位,而最多可能补512位 。补位的实现过程:首先在数据后补一个1 ; 接着在后面补上一堆0, 直到整个数据的位数对512求模的结果正好为448。将原文的原始长度用二进制表示储存在剩余的64bit中。最后的结果数据长度正好是512的整数倍。

  2. 设置初始值
    MD5 的哈希结果长度为 128 位,按每 32 位分成一组共 4 组。这 4 组结果是由 4 个初始值 A、B、C、D 经过不断演变得到。MD5 的官方实现中,A、B、C、D 的初始值如下(16 进制):

      A=0x01234567 
      B=0x89ABCDEF 
      C=0xFEDCBA98 
      D=0x76543210 
    
  3. 循环加工(最复杂就是这里了)
    首先定义4个非线性函数F、G、H、I(官方MD5使用的函数如下),对输入的报文运算以512位数据段为单位进行处理。对每个数据段都要进行4轮的逻辑处理,在4轮中分别使用4个不同的函数F、G、H、I。每一轮以ABCD和当前的512位的块为输入,处理后送入ABCD(128位) 。

     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))
    

那么要循环多少次呢?设处理后的原文长度为x,那么x/512 就是主循环次数,每个主循环包括512/32*4=64次子循环,其中4是表示被上面的F、G、H、I四个函数处理(第一个 16 次使用 F,第二个 16 次使用 G,第三个 16 次使用 H,第四个 16 次使用 I)。

下面是单次子循环的流程。
Alt
注释: F代表非线性函,也就是F、G、H、I这4个函数。红色“田”字表示相加的意思。Mi 是第一步处理后的原文。在第一步中,处理后原文的长度是 512 的整数倍。把原文的每 512 位再分成 16 等份,命名为 M0~M15,每一等份长度 32。在 64 次子循环中,每 16 次循环,都会交替用到 M1~M16 之一。Ki一个常量,在 64 次子循环中,每一次用到的常量都是不同的。黄色的<<<S:左移 S 位,S 的值也是常量。
新 ABCD 的产生可以归纳为:
新 A = 原 d
新 B = b+((a+F(b,c,d)+Mj+Ki)<<<s)
新 C = 原 b
新 D = 原 c

  1. 密文拼接
    就是把字符串拼接在一起。

为了更好的理解,来源于 百度百科 上的 MD5加密的C++代码如下:
`.

#include<iostream>
#include<string>
using namespace std;
#define shift(x, n) (((x) << (n)) | ((x) >> (32-(n))))//右移的时候,高位一定要补零,而不是补充符号位
#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 A 0x67452301
#define B 0xefcdab89
#define C 0x98badcfe
#define D 0x10325476
//strBaye的长度
unsigned int strlength;
//A,B,C,D的临时变量
unsigned int atemp;
unsigned int btemp;
unsigned int ctemp;
unsigned int dtemp;
//常量ti unsigned int(abs(sin(i+1))*(2pow32))
const unsigned int k[]={
   
        0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,
        0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,0x698098d8,
        0x8b44f7af,0xffff5bb1,0x895cd7be,0x6b901122,0xfd987193,
        0xa679438e,0x49b40821,0xf61e2562,0xc040b340,
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值