区块链应用开发指南:业务场景剖析与实战
上QQ阅读APP看书,第一时间看更新

2.3 区块链常用密码学知识

2.3.1 Hash(哈希)算法

基础知识

1.逻辑运算符。&(与):所有的都是真结果才是真;|“或”:至少一个为真结果也为真;~(非):真为假,假为真;^(异或):如果a、b两个值不相同,则异或结果为1,如果a、b两个值相同,异或结果为0。

2.字节序

  • 计算机硬件有两种储存数据的方式:大端字节序(big endian)和小端字节序(little endian)。
  • 举例来说,数值0x2211使用两个字节储存:高位字节是0x22,低位字节是0x11。
  • 大端字节序:高位字节在前,低位字节在后,这是人类读写数值的方法。小端字节序:低位字节在前,高位字节在后,即以0x1122形式储存。

3.循环移位

  • 循环右移就是当向右移时,把编码的最后的位移到编码的最前头,循环左移正相反。例如,对十进制编码12345678循环右移1位的结果为81234567,而循环左移1位的结果则为23456781。

什么是Hash算法

Hash算法是一种能将任意长度的二进制明文映射为较短的二进制串的算法,并且不同的明文很难映射为相同的Hash值。我们也可以把它理解为空间映射函数——是从一个非常大的取值空间映射到一个非常小的取值空间,由于不是一对一的映射,Hash函数转换后不可逆,也就是说,不可能通过逆操作和Hash值还原出原始的值。

Hash算法有什么特点

(1)正向快速:给定明文和Hash算法,在有限时间和有限资源内能计算得到Hash值。

(2)逆向困难:给定Hash值,在有限时间内很难逆推导出明文。

(3)输入敏感:原始输入信息发生任何变化,新的Hash值都应该出现很大变化。

(4)冲突避免:很难找到两段内容不同的明文,使得它们的Hash值一致。

常见Hash算法有哪些 MD5和SHA系列,目前MD5和SHA1已经被破解,而SHA2-256算法比较普遍被使用。

Hash算法碰撞 既然输入数据长度不固定,而输出的哈希值却是固定长度的,这意味着哈希值是一个有限集合,而输入数据则可以是无穷多个,所以建立一对一关系明显是不现实的。既然“碰撞”是必然会发生的,那么一个成熟的哈希算法要求具备较好的抗冲突性,同时在实现哈希表的结构时,也要考虑到哈希冲突的问题。

比如“666”经过Hash后,其哈希值是“fae0b27c451c728867a567e8c1bb4e53”,相同Hash算法得到的值是一样的。比如WiFi密码如果是8位纯数字的话,顶多就是99999999种可能性,破解这个密码需要做的就是提前生成好0到1亿数字的Hash值,然后做1亿次布尔运算(就是Bool值判断,0或者1),而现在普通Intel i5四核CPU(每秒能到达200亿次浮点数计算)做1亿次布尔运算,也就是秒级别的时间就破解了。因此,密码尽量不要用纯数字,密码空间有限会导致很难构建高安全性。

加盐防碰撞

常用的防止“碰撞”的方式,就是加盐(Salt)。其实现原理,就是在原来的明文,加上一个随机数之后,再进行运算的Hash值,Hash值和盐通常会分别保存在两个不同的地方,同时泄露才可能被破解。

  • MD5算法属于Hash算法中的一种,它具有以下特性:输入任意长度的信息,经过处理,输出为128位的信息(数字指纹)。不同的输入得到不同的结果(唯一性)。根据128位的输出结果不可能反推出输入的信息(不可逆)。可见其继承了Hash算法的优良特点,用处很多,如登录密码、数字签名等。

算法实现介绍

MD5是以512位分组来处理输入的信息,每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组拼接后生成一个128位Hash值,具体步骤如下:

填充:假如原始信息长度对512求余的结果不等于448(这里说的单位是bit,就是位,1字节(Byte)= 8位(bit)),就需要填充使得对512求余的结果等于448。填充的方法是填充一个1和m个0。填充完后,信息的长度就为n × 512 + 448(这里n表示的是512的整数倍,注意:n也可以为0)。

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

设置初始值:MD5的哈希结果长度为128位,按每32位分成一组共4组,这4组结果是由4个初始值A、B、C、D经过不断计算得到的,分别为16进制的A =0x67452301,B = 0x0EFCDAB89,C = 0x98BADCFE,D = 0x10325476。

准备四个逻辑运算函数:

F(X,Y,Z)=(X & Y)|((~X)& Z)G(X,Y,Z)=(X & Z)|(Y &(~Z))H(X,Y,Z)= X ^ Y ^Z J(X,Y,Z)= Y ^(X |(~Z))

把原始消息数据分成以512位为一组进行处理,每一组进行4轮变换,每一轮对应上面的逻辑运算函数。

每一轮中会把512位的数据按照每一小块32位长度分成16块数据,进行16次计算,每一次计算会把对ABCD中的其中三个作一次逻辑运算,然后将所得结果加上第四个变量,16块数据其中一块数据和一个常数。再将所得结果向左环移一个规定的数量,并加上ABCD中之一。最后用该结果取代ABCD中之一。

以上面所说的4个常数ABCD为起始变量进行计算,重新输出4个变量,以这4个变量再进行下一分组的运算,如果已经是最后一个分组,则这4个变量为最后的结果,即MD 5值。