在很多技术人员的眼中,区块链并不是一种新的技术,而是过去很多年计算机技术的组合运用。而在这个方方面面技术的运用上,基于密码学的加密算法可以说是区块链各种特点得以表现的根本,一旦目前使用的加密算法被证实可以破解,那么现有的区块链技术很有可能土崩瓦解。本文所要讲述的就是目前区块链中运用最广的加密算法:SHA256。

SHA是一个密码散列函数家族,是英文Secure Hash Algorithm的缩写。由美国国家安全局(NSA)所设计,并由美国国家标准与技术研究院(NIST)发布。本文的主角SHA256算法就是这个家族中的一员。在此之前的SHA0,SHA1都被证明是可以破解的,目前SHA2以及SHA3尚未被证实可以破解。这里引申一下,在密码学的定义中,所谓可以破解,即是计算复杂度少于暴力破解所需要的计算复杂度。SHA256中的256取的这种算法的摘要长度。下面会具体讲一下SHA256的实现原理。

SHA256算法的设计思路主要是依赖于一个优秀的HASH散列算法的特点:任何微小的输入都有可能对输出产生巨大的影响,以及HASH算法极低的碰撞概率。

常量定义:

SHA256算法中首先规定了8个哈希初值和64个哈希常量。8个哈希初值取的是自然数中前8个质数(2,3,5,7,11,13,17,19)的平方根的小数部分的前32bit的值。例如:

 
取小数部分:(用16进制表示)

所以8个哈希初值的第一个可以表示为: h0 : = 0X6a09e667。最终取到的8个哈希初值分别是:

  1. H0= 0x6a09e667 H1 = 0xbb67ae85 H2 = 0x3c6ef372 H3 = 0xa54ff53a H4 = 0x510e527f
    H5 = 0x9b05688c H6 = 0x1f83d9ab H7 = 0x5be0cd19

在看前面8个哈希初值的定义,64个哈希常量的定义是取自然数中前64个质数的立方根的小数部分的前32bit的值。这里就不贴出来了,了解定义即可。细心的读者应该能发现,8个哈希初值,每个32位,总长度对应的就是SHA256算法的最后结果的长度。

逻辑函数定义:

SHA256算法定义了6种逻辑函数,这6个逻辑函数的作用这里先简单了解,后续的代码部分会看到如何使用。

备注: AND 表示”与“运算,NOT 表示:”或“运算,XOR 表示”异或“运算。ROTR^2(X)表示对X进行循环右移两位,SHR^3(X)表示对X右移三位。函数的输入都是32bit的字。

  1.   CHx, y, z) = (x AND y) XOR ( (NOT x) AND z)  
          MAJ( x, y, z) = (x AND y) XOR (x AND z) XOR (y AND z)  
          BSIG0(x) = ROTR^2(x) XOR ROTR^13(x) XOR ROTR^22(x)  
          BSIG1(x) = ROTR^6(x) XOR ROTR^11(x) XOR ROTR^25(x)  
          SSIG0(x) = ROTR^7(x) XOR ROTR^18(x) XOR SHR^3(x)  
          SSIG1(x) = ROTR^17(x) XOR ROTR^19(x) XOR SHR^10(x)

算法过程:

补位:

补位的目的是为了使消息长度满足: (消息原始长度+1+K) mod 512 = 448 这个公式。为什么是448,目的是为了后续留有64位的长度来表示消息的长度,SHA256支持的消息长度是不大于2的64次方。1表示补位第一步补的一个位,K表示需要补的0的个数。补位的第一步是不管消息长度多少(即使对512去模等于448),都在末尾补一个1。

假设原始消息是这样: 01111101 01110000 11110000 00000001

补位第一步后的消息: 01111101 01110000 11110000 00000001 1

根据上面的解释很容易算出需要补 415个0。

补长度:

补充的长度一般是固定的64bit,用来表示消息的初始长度。上面输入的长度是32位,转换成2进制是100000。所以将会把100000补在上面的消息后面,不足64位在前面补0。

计算过程:

整体思路:把消息分成大小512bit的N份,取第一个数据块的数据,分成16份32bit的数组。最开始的8个哈希初值H(0)经过第一个消息块数据运算得到H(1),经过第二个消息块数据运算得到H(2),一次循环,直到得到H(N),就是最后得到的信息摘要。

详细的过程如下:

1)首先使用一个256-bit 的缓存来存放该散列函数的中间及最终结果。我们前面提到SHA256中定义了8个初始值,这8个初始值用a,b,c,d,e,f,g,h表示:a=0x6a09e667, b=0xbb67ae85, c=0x3c6ef372, d=0xa54ff53a, e=0x510e527f, f=0x9b05688c, g=0x1f83d9ab, h=0x5be0cd19。

2)把补长过的消息进行拆分成N个512bit数据。首先计算函数的外部有个大的循环,形如: For i =1 to N;

3 ) 在每一次的循环里,需要给函数W(t)的输入t为0到63的结果赋值,即W(0),W(1),W(2)...W(63)。其中W(0)到W(15)的值为当前快消息被拆分的16个值(前面提到的每个块分成16个32bit的数据)。然后W(16)到W(63)取的值为依赖前面16个值产生,具体算法如下 :

  1. For t = 0 to 15

    Wt = M(i)t   //赋值W(t)的前16个值

    For t = 16 to 63

    Wt = SSIG1(W(t-2)) + W(t-7) + SSIG0(w(t-15)) + W(t-16) //利用W(t)前面的16个值计算后面的值

4)利用第三步取到的W(t)的64个值,进行64次循环,打乱原有的顺序。过程中有一些中间变量,但是目的是为了重新给a,b,c,d,e,f,g,h赋值。代码过程:

  1. For t = 0 to 63    

    T1 = h + BSIG1(e) + CH(e,f,g) + Kt + Wt   //Kt是前面用到的64个定义值

    T2 = BSIG0(a) + MAJ(a,b,c)

    h = g

    g = f

    f = e

    e = d + T1

    d = c

    c = b

    b = a

    a = T1 + T2

可以看到,利用之前介绍的逻辑函数和第三步的运算结果,重新计算了a,b,c,d,e,f,g,h的值。

5) 最后一步就是根据第四步重新赋值的8个变量得出这个块的SHA256结果。

  1. H(i)0 = a + H(i-1)0   //a是一个32bit的值,H(i-1)0也是一个32bit的值

    H(i)1 = b + H(i-1)1

    H(i)2 = c + H(i-1)2

    H(i)3 = d + H(i-1)3

    H(i)4 = e + H(i-1)4

    H(i)5 = f + H(i-1)5

    H(i)6 = g + H(i-1)6

    H(i)7 = h + H(i-1)7

到这里,第一次循环就结束了,还记得之前提过的”外部有个大的循环,形如: For i =1 to N “ 吗?在SHA256中,消息的长度越长,循环的次数也越多。经过N此循环得到H(N)0,H(N)1,H(N)2,...H(N)7,8个32位的数拼接起来就形成了SHA256算法的最终结果:一个长度为256位的消息摘要。

在比特币中,SHA256运用在了钱包地址的产生,也是实现pow共识机制的主要手段。就目前来说,2的256次方近似于10的77次方,10的77次方有多大?到目前为止,人类可观测的宇宙中的原子数约为10的80次方,这种数量级的散列算法想要通过碰撞来攻击基本是不可能的。这也是目前为什么SHA256算法得到普遍应用的原因之一。

区块链中的密码学(-)区块链中运用最广的散列算法-SHA256算法分析与实现的更多相关文章

  1. shiro中自定义realm实现md5散列算法加密的模拟

    shiro中自定义realm实现md5散列算法加密的模拟.首先:我这里是做了一下shiro 自定义realm散列模拟,并没有真正链接数据库,因为那样东西就更多了,相信学到shiro的人对连接数据库的一 ...

  2. 密码学奇妙之旅、03 HMAC单向散列消息认证码、Golang代码

    HMAC 单向散列消息认证码 消息认证码MAC是用于确认完整性并进行认证的技术,消息认证码的输入包括任意长度的消息和一个发送者和接收者之间共享的密钥(可能还需要共享盐值). HMAC是使用单向散列函数 ...

  3. java 解决Hash(散列)冲突的四种方法--开放定址法(线性探测,二次探测,伪随机探测)、链地址法、再哈希、建立公共溢出区

    java 解决Hash(散列)冲突的四种方法--开放定址法(线性探测,二次探测,伪随机探测).链地址法.再哈希.建立公共溢出区 标签: hashmaphashmap冲突解决冲突的方法冲突 2016-0 ...

  4. 散列数据结构以及在HashMap中的应用

    1. 为什么需要散列表? 对于线性表和链表而言,访问表中的元素,时间复杂度均为O(n).即便是通过树结构存储数据,时间复杂度也为O(logn).那么有没有一种方式可以将这个时间复杂度降为O(1)呢?当 ...

  5. Python中的hashable(散列)

    Python文档中的解释: 一个对象是可散列的,那么在它的生命周期中它的hash 值是不变的. 可散列的对象需要2个方法:__hash__()方法和__eq__()方法.两个可散列的对象相等,那么它们 ...

  6. 区块链中的密码学(四)- Merkle树和SPV节点

    什么是Merkle Tree? Merkle Tree 的命名来自于美国密码学家Ralph C. Merkle ,关于他的个人资料:传送门https://en.wikipedia.org/wiki/R ...

  7. 区块链Fabric技术在托管业务中的运用初探

    区块链Fabric技术在托管业务中的运用初探 什么是Fabric技术 HyperLedger是IBM.Intel等多家公司正开展的一个区块链项目,包含了Fabric.Iroha等多项技术,其中最为活跃 ...

  8. 未来-区块链-IBM:IBM 区块链技术开发社区

    ylbtech-未来-区块链-IBM:IBM 区块链技术开发社区 1.返回顶部 1. 开始学习 IBM Blockchain 101:开发人员快速入门指南 这篇快速入门指南适合不熟悉区块链技术,希望快 ...

  9. cpp 区块链模拟示例(四) 区块链工作量证明

    本文主要在之前的区块链原形上添加了工作量证明,并且为后继的交易功能做好准备. 上一个章节我们已经创建了区块链的基本原形,但是区块的哈希计算和加入太过于简单,如果按照这种速度添加区块那么区块链估计一个小 ...

随机推荐

  1. 机器学习:集成学习(OOB 和 关于 Bagging 的更多讨论)

    一.oob(Out - of - Bag) 定义:放回取样导致一部分样本很有可能没有取到,这部分样本平均大约有 37% ,把这部分没有取到的样本称为 oob 数据集: 根据这种情况,不对数据集进行 t ...

  2. java基础知识(15)----StringBuffer与StringBuilder

    StringBuffer字符串缓冲区: 构造一个其中不带字符的字符串缓冲区,初始容量为 16 个字符.特点:1:可以对字符串内容进行修改.2:是一个容器.3:是可变长度的.4:缓冲区中可以存储任意类型 ...

  3. 使用svn进行本地代码管理

    简述 这里讨论的是如何管理自己个人电脑的个人项目的代码.和SVN服务器配置无关. 可以先到TortoiseSVN官网下载安装包进行安装. 代码仓库管理 比如现在有一个工程需要进行管理,可以先将该工程放 ...

  4. MySQL启动失败解决办法

    本人大二,进了一家培训机构学了两年,然后跟着他们做项目,其实也是练习,然后过程中遇到好多错误,当时解决了,然后下次遇到又忘了,-_-!  -_-||| 我就想通过写博客来记载一下我遇到的错误和解决的办 ...

  5. MySQL查询某个字段为某值的次数统计SQL语句

    SELECT GoodID,sum(if(Level = 1, 1, 0)) as Better,sum(if(Level = 0, 1, 0)) as Nomal,sum(if(Level = -1 ...

  6. eclipse DDMS导出文件失败--android Failed to push the item

    我们在写安卓程序的时候,经常会用Eclipse导出模拟器的文件管理里面的文件,但有时候会报错,导致无法导出文件. 报错信息 Failed to push selection: Local path d ...

  7. hive删除表报错:Specified key was too long; max key length&nb

    我是在hive删除表的时候出现这个错误的,看到这个错误应该就知道是字符集错误. 但是我用​ alter database hive character set latin1; 这个命令将其改成拉丁之后 ...

  8. poj1753-Flip Game 【状态压缩+bfs】

    http://poj.org/problem?id=1753 Flip Game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions ...

  9. Python中for else注意事项

    假设有如下代码: for i in range(10): if i == 5: print 'found it! i = %s' % i else: print 'not found it ...' ...

  10. cocos2dx中坐标系

    CCNode类的setPosition,getPosition函数如果是一个Node的Child则获取的坐标就是该Node的本地坐标 另一个关键问题就是在cocos2d-x里就是各种对象的大小问题.因 ...