16、HASH算法-摘要-散列

目录

HASH函数

MD5

SHA-1

SHA-256


参考转载:

https://blog.csdn.net/u011583927/article/details/80905740

Hash算法的讲解 

hash算法原理详解

SM3密码杂凑算法

HASH函数

1、HASH算法

目前流行的hash算法有MD5、SHA-1、SHA-256以及国产SM3算法。

2、安全的散列函数应满足的条件

1)输入长度是任意的,输出长度是固定的;

2)单向性:对每个给定的输入,计算其杂凑值很容易;给定杂凑值,找到满足的输入是不可行的;

3)抗碰撞:给定杂凑函数的描述,找到两个不同的输入信息杂凑到同一个值是不可行的;

4)抗生日攻击(强弱而已)

3、Hash算法在信息安全方面的应用

数据一致性/完整性验证:数据一致性说得是如何保证一段数据在传输的过程中没有遗漏、破坏或者修改过。一般来说,目前流行的做法是对数据进行hash,得到的hash值和数据一起传输,然后在收到数据的时候也对数据进行hash,将得到的hash值和传输过来的hash值进行比对,如果是不一样的,说明数据已经被修改过;如果是一样的,则说明极有可能是完整的。

文件校验:我们比较熟悉的校验算法有奇偶校验和CRC校验,这2种校验并没有抗数据篡改的能力,它们一定程度上能检测并纠正数据传输中的信道误码,但却不能防止对数据的恶意破坏。MD5 Hash算法的"数字指纹"特性,使它成为目前应用最广泛的一种文件完整性校验和(Checksum)算法,不少Unix系统有提供计算md5 checksum的命令。

数字签名:Hash 算法也是现代密码体系中的一个重要组成部分。由于非对称算法的运算速度较慢,所以在数字签名协议中,单向散列函数扮演了一个重要的角色。 对 Hash 值,又称"数字摘要"进行数字签名,在统计上可以认为与对文件本身进行数字签名是等效的。而且这样的协议还有其他的优点。

鉴权协议:鉴权协议又被称作挑战--认证模式:在传输信道是可被侦听,但不可被篡改的情况下,这是一种简单而安全的方法。

MD5

MD5信息摘要算法(MD5 Message-Digest Algorithm),一种被广泛使用的密码杂凑函数,可以产生出一个128位(16位元组)的散列值(hash value),用于确保信息传输完整一致。

一、MD5算法过程

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

1、填充:如果输入信息的长度(bit)对512求余的结果不等于448,就需要填充使得对512求余的结果等于448。填充的方法是填充一个1和n个0。填充完后,信息的长度就为N*512+448(bit);

2、记录信息长度:用64位来存储填充前信息长度。这64位加在第一步结果的后面,这样信息长度就变为N*512+448+64=(N+1)*512位。

3、装入标准的幻数(四个整数):标准的幻数(物理顺序)是(A=(01234567)16,B=(89ABCDEF)16,C=(FEDCBA98)16,D=(76543210)16)。如果在程序中定义应该是:

(A=0X67452301L,B=0XEFCDAB89L,C=0X98BADCFEL,D=0X10325476L)

4、四轮循环运算:循环的次数是分组的个数(N+1)

1)将每一512字节细分成16个小组,每个小组64位(8个字节)

2)先认识四个线性函数(&是与,|是或,~是非,^是异或)

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

3)设Mj表示消息的第j个子分组(从0到15),<<

        FF(a,b,c,d,Mj,s,ti)表示a=b+((a+F(b,c,d)+Mj+ti)<<<s)

        GG(a,b,c,d,Mj,s,ti)表示a=b+((a+G(b,c,d)+Mj+ti)<<<s)

        HH(a,b,c,d,Mj,s,ti)表示a=b+((a+H(b,c,d)+Mj+ti)<<<s)

        II(a,b,c,d,Mj,s,ti)表示a=b+((a+I(b,c,d)+Mj+ti)<<<s)

4)四轮运算

5)每轮循环后,将A,B,C,D分别加上a,b,c,d,然后进入下一循环。

二、MD5算法相关

1、MD5功能

输入任意长度的信息,经过处理,输出为128位的信息(数字指纹);

不同的输入得到的不同的结果(唯一性);

2、MD5用途

防篡改:

比如发送一个电子文档,发送前,我先得到MD5的输出结果a。然后在对方收到电子文档后,对方也得到一个MD5的输出结果b。如果a与b一样就代表中途未被篡改。

比如我提供文件下载,为了防止不法分子在安装程序中添加木马,我可以在网站上公布由安装文件得到的MD5输出结果。

SVN在检测文件是否在CheckOut后被修改过,也是用到了MD5.

防止直接看到明文:

现在很多网站在数据库存储用户的密码的时候都是存储用户密码的MD5值。这样就算不法分子得到数据库的用户密码的MD5值,也无法知道用户的密码。(比如在UNIX系统中用户的密码就是以MD5(或其它类似的算法)经加密后存储在文件系统中。当用户登录的时候,系统把用户输入的密码计算成MD5值,然后再去和保存在文件系统中的MD5值进行比较,进而确定输入的密码是否正确。通过这样的步骤,系统在并不知道用户密码的明码的情况下就可以确定用户登录系统的合法性。这不但可以避免用户的密码被具有系统管理员权限的用户知道,而且还在一定程度上增加了密码被破解的难度。)

防止抵赖(数字签名):

这需要一个第三方认证机构。例如A写了一个文件,认证机构对此文件用MD5算法产生摘要信息并做好记录。若以后A说这文件不是他写的,权威机构只需对此文件重新产生摘要信息,然后跟记录在册的摘要信息进行比对,相同的话,就证明是A写的了。这就是所谓的“数字签名”。

3、MD5不属于加密算法

认为不属于的人是因为他们觉得不能从密文(散列值)反过来得到原文,即没有解密算法,所以这部分人认为MD5只能属于算法,不能称为加密算法;认为属于的人是因为他们觉得经过MD5处理后看不到原文,即已经将原文加密,所以认为MD5属于加密算法;我个人支持前者,正如认为BASE64算法只能算编码一样。

4、MD5算法不可逆

MD5不可逆的原因是其是一种散列函数,使用的是hash算法,在计算过程中原文的部分信息是丢失了的。

不过有个地方值得指出的是,一个MD5理论上的确是可能对应无数多个原文的,因为MD5是有限多个的而原文可以是无数多个。比如主流使用的MD5将任意长度的“字节串映射为一个128bit的大整数。也就是一共有2^128种可能,大概是3.4*10^38,这个数字是有限多个的,而但是世界上可以被用来加密的原文则会有无数的可能性。

不过需要注意的一点是,尽量这是一个理论上的有限对无限,不过问题是这个无限在现实生活中并不完全成立,因为一方面现实中原文的长度往往是有限的(以常用的密码为例,一般人都在20位以内),另一方面目前想要发现两段原文对应同一个MD5(专业的说这叫杂凑冲撞)值非常困难,因此某种意义上来说,在一定范围内想构建MD5值与原文的一一对应关系是完全有可能的。所以对于MD5目前最有效的攻击方式就是彩虹表。

MD5相当于超损压缩。

5、MD5安全性

普遍认为MD5是很安全,因为暴力破解的时间是一般人无法接受的。实际上如果把用户的密码MD5处理后再存储到数据库,其实是很不安全的。因为用户的密码是比较短的,而且很多用户的密码都使用生日,手机号码,身份证号码,电话号码等等。或者使用常用的一些吉利的数字,或者某个英文单词。如果我把常用的密码先MD5处理,把数据存储起来,然后再跟你的MD5结果匹配,这时我就有可能得到明文。比如某个MD5破解网站http://www.cmd5.com/default.aspx,所以现在大多数网站密码的策略是强制要求用户使用数字大小写字母的组合的方式提高用户密码的安全度。

SHA-1

1、消息填充 

2、初始化缓冲区

3、执行算法主循环 

        核心:压缩函数 

SHA-256

为了更好的理解SHA256的原理,这里首先将算法中可以单独抽出的模块,包括常量的初始化、信息预处理、使用到的逻辑运算分别进行介绍,甩开这些理解上的障碍后,一起来探索SHA256算法的主体部分,即消息摘要是如何计算的。

1 、常量初始化

SHA256算法中用到了8个哈希初值以及64个哈希常量。

其中,SHA256算法的8个哈希初值如下:

h0 := 0x6a09e667;h1 := 0xbb67ae85;h2 := 0x3c6ef372;h3 := 0xa54ff53a;

h4 := 0x510e527f;h5 := 0x9b05688c;h6 := 0x1f83d9ab;h7 := 0x5be0cd19;

于是,质数2的平方根的小数部分取前32bit就对应出了0x6a09e667

在SHA256算法中,用到的64个常量如下:

428a2f98 71374491 b5c0fbcf e9b5dba5

3956c25b 59f111f1 923f82a4 ab1c5ed5

d807aa98 12835b01 243185be 550c7dc3

72be5d74 80deb1fe 9bdc06a7 c19bf174

e49b69c1 efbe4786 0fc19dc6 240ca1cc

2de92c6f 4a7484aa 5cb0a9dc 76f988da

983e5152 a831c66d b00327c8 bf597fc7

c6e00bf3 d5a79147 06ca6351 14292967

27b70a85 2e1b2138 4d2c6dfc 53380d13

650a7354 766a0abb 81c2c92e 92722c85

a2bfe8a1 a81a664b c24b8b70 c76c51a3

d192e819 d6990624 f40e3585 106aa070

19a4c116 1e376c08 2748774c 34b0bcb5

391c0cb3 4ed8aa4a 5b9cca4f 682e6ff3

748f82ee 78a5636f 84c87814 8cc70208

90befffa a4506ceb bef9a3f7 c67178f2

和8个哈希初值类似,这些常量是对自然数中前64个质数(2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97…)的立方根的小数部分取前32bit而来。

2、信息预处理(pre-processing)

SHA256算法中的预处理就是在想要Hash的消息后面补充需要的信息,使整个消息满足指定的结构。信息的预处理分为两个步骤:附加填充比特和附加长度

1)附加填充比特:

在报文末尾进行填充,使报文长度在对512取模以后的余数是448;填充方式:先补第一个比特为1,然后都补0,直到长度满足对512取模后余数是448。需要注意的是,信息必须进行填充,也就是说,即使长度已经满足对512取模后余数是448,补位也必须要进行,这时要填充512个比特。因此,填充是至少补一位,最多补512位。

为什么是448?因为在第一步的预处理后,第二步会再附加上一个64bit的数据,用来表示原始报文的长度信息。而448+64=512,正好拼成了一个完整的结构。

2)附加长度值:

附加长度值就是将原始数据(第一步填充前的消息)的长度信息补到已经进行了填充操作的消息后面。SHA256用一个64位的数据来表示原始消息的长度。因此,通过SHA256计算的消息长度必须要小于2^64 ,当然绝大多数情况这足够大了。

回到刚刚的例子,消息“abc”,3个字符,占用24个bit;因此,在进行了补长度的操作以后,整个消息就变成16进制格式;

61626380 00000000 00000000 00000000

00000000 00000000 00000000 00000000

00000000 00000000 00000000 00000000

00000000 00000000 00000000 00000018

3、 逻辑运算

SHA256散列函数中涉及的操作全部是逻辑的位运算;包括如下的逻辑函数:

其中:

逻辑运算

含义

按位“与”

¬

按位“补”

按位“异或”

S^{n}

循环右移n个bit

R^{n}

右移n个bit

4、 计算消息摘要

现在来介绍SHA256算法的主体部分,即消息摘要是如何计算的。

首先:消息分组,将消息分解成512-bit大小的块

假设消息M可以被分解为n个块,于是整个算法需要做的就是完成n次迭代,n次迭代的结果就是最终的哈希值,即256bit的数字摘要;一个256bit的摘要的初始值H0,经过第一个数据块进行运算,得到H1,即完成了第一次迭代;H1经过第二个数据块得到H2,……,依次处理,最后得到Hn,Hn即为最终的256bit消息摘要;将每次迭代进行的映射用Map(H{i-1}) = H{i}表示,于是迭代可以更形象的展示为:

图中256-bit的Hi被描述8个小块,这是因为SHA256算法中的最小运算单元称为“字”(Word),一个字是32位。此外,第一次迭代中,映射的初值设置为前面介绍的8个哈希初值,如下图所示:

下面开始介绍每一次迭代的内容:

1):构造64个字(word)

对于每一块,将块分解为16个32bit的big-endian的字,记为w[0], …, w[15];也就是说,前16个字直接由消息的第i个块分解得到

其余的字由如下迭代公式得到:

Wt​=σ1​(Wt−2​)+Wt−7​+σ0​(Wt−15​)+Wt−16​

2):进行64次循环

映射包含了64次加密循环,即进行64次加密循环即可完成一次迭代;每次加密循环可以由下图描述:

图中,ABCDEFGH这8个字(word)在按照一定的规则进行更新,其中:

  • 深蓝色方块是事先定义好的非线性逻辑函数,即将两个数字加在一起,如果结果大于2^{32} ,你必须除以 2^{32}并找到余数。
  • ABCDEFGH一开始的初始值分别为H{i-1}(0),H{i-1}(1),…,H{i-1}(7)
  • Kt是第t个密钥,对应我们上文提到的64个常量
  • Wt是本区块产生第t个word。原消息被切成固定长度512-bit的区块,对每一个区块,产生64个word,通过重复运行循环n次对ABCDEFGH这八个字循环加密。
  • 最后一次循环所产生的八个字合起来即是第i个块对应到的散列字符串H{i}

补: 

注:

如有错误、侵权,请联系作者更改删除!!!

猜你喜欢

转载自blog.csdn.net/weixin_42369053/article/details/118309215