MD5设计原理

Hash函数
Hash函数与数据完整性

密码学上的Hash函数可为数据完整性提供保障。Hash 函数通常用来构造数据的短“指纹”: . - " 旦数据改变,指纹就不再正确。即使数据被存储在不安全的地方,通过重新计算数据的指纹并验证指纹是否改变,就能够检测数据的完整性。

首先给出带密钥的Hash族的定义。
定义4.1 - 一个Hash族是满足下列条件的四元组(X,Y, K, H):
1. x是所有可能的消息的集合。
2. Y是由所有可能的消息摘要或认证标签构成的有限集。
3. K是密钥空间,是所有可能的密钥构成的有限集。
4. 对每个k∈K,存在一个Hash函数h(k)∈H, h(k):X→Y。
在上面的定义中,X可以是有限或无限集; Y总是有限集。如果X是有限集,则Hash函数常常称为压缩函数。这时,我们总是假定|X|≥|Y|,并且还经常假定更强的条件|X|≥2|Y|。

Hash函数随机谕示模型及安全性(数学公式太多直接贴图啦!)

总而言之:Hash函数本身是有安全性困扰,即加密可逆,但是经过一定的数学计算,伟大的科学家们创造了一种模型,在这个模型下可以大大的减少这种被破解的可能。而在这个模型中,通常建议一个消息摘要可接受的最小长度为128比特。

  • 这是一般的Hash函数可以被容易找到加密前的原文的三种情况
    这是一般的Hash函数可以被容易找到加密前的原文的三种情况
  • 这是一些算法来解决上一张图容易被找到原文的问题
    这是一些算法来解决上一张图容易被找到原文的问题
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
MD5基本原理
MD5是啥

在这里插入图片描述
MD5是一种信息摘要算法,基于hash函数散列,有以下特点:

  1. 压缩性:无论数据长度是多少,计算出来的MD5值长度相同(通常使用的是128bit,也是最容易被破解的,加强版有256bit的)
  2. 容易计算性:由原数据容易计算出MD5值(具体的计算过程见原理)
  3. 抗修改性:即便修改一个字节,计算出来的MD5值也会巨大差异(如上图)
  4. 抗碰撞性:知道数据和MD5值,很小概率找到相同MD5值相同的原数据(目前所知的2^20.96的碰撞(碰撞即穷举)算法复杂度,可以破解MD5的碰撞抵抗)
MD5原理

在这里插入图片描述

  • 原文分组 MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。

  • 设置初始值 在MD5算法中,首先需要对信息进行填充,使其字节长度对512求余数的结果等于448。因此,信息的字节长度(Bits Length)将被扩展至N512+448,即N64+56个字节(Bytes),N为一个正整数。填充的方法如下,在信息的后面填充一个1和无数个0,直到满足上面的条件时才停止用0对信息的填充。然后再在这个结果后面附加一个以64位二进制表示的填充前的信息长度。经过这两步的处理,现在的信息字节长度=N*512+448+64=(N+1)*512,即长度恰好是512的整数倍数。这样做的原因是为满足后面处理中对信息长度的要求。MD5中有四个32位被称作链接变量(Chaining Variable)的整数参数,他们分别为:A=0x01234567,B=0x89abcdef,C=0xfedcba98,D=0x76543210。当设置好这四个链接变量后,就开始进入算法的四轮循环运算,循环的次数是信息中512位信息分组的数目。

  • 循环加工将上面四个链接变量复制到另外四个变量中:A到a,B到b,C到c,D到d。主循环有四轮(MD4只有三轮),每轮循环都很相似。第一轮进行16次操作。每次操作对a、b、c和d中的其中三个作一次非线性函数运算,然后将所得结果加上第四个变量(文本中的一个子分组和一个常数)。

  • 拼接组装 再将所得结果向右环移一个不定的数,并加上a、b、c或d中之一。最后用该结果取代a、b、c或d中之一。以一下是每次操作中用到的四个非线性函数(每轮一个)。
    在这里插入图片描述
    其中,?是异或,∧是与,∨是或,是反符号。

如果X、Y和Z的对应位是独立和均匀的,那么结果的每一位也应是独立和均匀的。F是一个逐位运算的函数。即,如果X,那么Y,否则Z。函数H是逐位奇偶操作符。所有这些完成之后,将A,B,C,D分别加上a,b,c,d。然后用下一分组数据继续运行算法,最后的输出是A,B,C和D的级联。最后得到的A,B,C,D就是输出结果,A是低位,D为高位,DCBA组成128位输出结果。

MD5实现
//Note: All variables are unsigned 32 bits and wrap modulo 2^32 when calculating
var int[64] r, k

//r specifies the per-round shift amounts
r[ 0..15]:= {7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22} 
r[16..31]:= {5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20}
r[32..47]:= {4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23}
r[48..63]:= {6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21}

//Use binary integer part of the sines of integers as constants:
for i from 0 to 63
    k[i] := floor(abs(sin(i + 1)) × 2^32)

//Initialize variables:
var int h0 := 0x67452301
var int h1 := 0xEFCDAB89
var int h2 := 0x98BADCFE
var int h3 := 0x10325476

//Pre-processing:
append "1" bit to message
append "0" bits until message length in bits ≡ 448 (mod 512)
append bit length of message as 64-bit little-endian integer to message

//Process the message in successive 512-bit chunks:
for each 512-bit chunk of message
    break chunk into sixteen 32-bit little-endian words w[i], 0 ≤ i ≤ 15

    //Initialize hash value for this chunk:
    var int a := h0
    var int b := h1
    var int c := h2
    var int d := h3

    //Main loop:
    for i from 0 to 63
        if 0 ≤ i ≤ 15 then
            f := (b and c) or ((not b) and d)
            g := i
        else if 16 ≤ i ≤ 31
            f := (d and b) or ((not d) and c)
            g := (5×i + 1) mod 16
        else if 32 ≤ i ≤ 47
            f := b xor c xor d
            g := (3×i + 5) mod 16
        else if 48 ≤ i ≤ 63
            f := c xor (b or (not d))
            g := (7×i) mod 16
 
        temp := d
        d := c
        c := b
        b := leftrotate((a + f + k[i] + w[g]),r[i]) + b
        a := temp
    Next i
    //Add this chunk's hash to result so far:
    h0 := h0 + a
    h1 := h1 + b 
    h2 := h2 + c
    h3 := h3 + d
End ForEach
var int digest := h0 append h1 append h2 append h3 //(expressed as little-endian)

密码学原理与实践(第三版) (Chinese) Paperback – January 1, 2016
by [加] Douglas R. Stinson 道格拉斯 R. 斯廷森 著,冯登国 等译 (Author)
https://en.wikipedia.org/wiki/MD5
https://www.cnblogs.com/sthu/p/9981328.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值