区块链中的密码学(-)区块链中运用最广的散列算法-SHA256算法分析与实现
在很多技术人员的眼中,区块链并不是一种新的技术,而是过去很多年计算机技术的组合运用。而在这个方方面面技术的运用上,基于密码学的加密算法可以说是区块链各种特点得以表现的根本,一旦目前使用的加密算法被证实可以破解,那么现有的区块链技术很有可能土崩瓦解。本文所要讲述的就是目前区块链中运用最广的加密算法: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的值。例如:
所以8个哈希初值的第一个可以表示为: h0 : = 0X6a09e667。最终取到的8个哈希初值分别是:
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的字。
CH(x, 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个值产生,具体算法如下 :
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赋值。代码过程:
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结果。
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算法分析与实现的更多相关文章
- shiro中自定义realm实现md5散列算法加密的模拟
shiro中自定义realm实现md5散列算法加密的模拟.首先:我这里是做了一下shiro 自定义realm散列模拟,并没有真正链接数据库,因为那样东西就更多了,相信学到shiro的人对连接数据库的一 ...
- 密码学奇妙之旅、03 HMAC单向散列消息认证码、Golang代码
HMAC 单向散列消息认证码 消息认证码MAC是用于确认完整性并进行认证的技术,消息认证码的输入包括任意长度的消息和一个发送者和接收者之间共享的密钥(可能还需要共享盐值). HMAC是使用单向散列函数 ...
- java 解决Hash(散列)冲突的四种方法--开放定址法(线性探测,二次探测,伪随机探测)、链地址法、再哈希、建立公共溢出区
java 解决Hash(散列)冲突的四种方法--开放定址法(线性探测,二次探测,伪随机探测).链地址法.再哈希.建立公共溢出区 标签: hashmaphashmap冲突解决冲突的方法冲突 2016-0 ...
- 散列数据结构以及在HashMap中的应用
1. 为什么需要散列表? 对于线性表和链表而言,访问表中的元素,时间复杂度均为O(n).即便是通过树结构存储数据,时间复杂度也为O(logn).那么有没有一种方式可以将这个时间复杂度降为O(1)呢?当 ...
- Python中的hashable(散列)
Python文档中的解释: 一个对象是可散列的,那么在它的生命周期中它的hash 值是不变的. 可散列的对象需要2个方法:__hash__()方法和__eq__()方法.两个可散列的对象相等,那么它们 ...
- 区块链中的密码学(四)- Merkle树和SPV节点
什么是Merkle Tree? Merkle Tree 的命名来自于美国密码学家Ralph C. Merkle ,关于他的个人资料:传送门https://en.wikipedia.org/wiki/R ...
- 区块链Fabric技术在托管业务中的运用初探
区块链Fabric技术在托管业务中的运用初探 什么是Fabric技术 HyperLedger是IBM.Intel等多家公司正开展的一个区块链项目,包含了Fabric.Iroha等多项技术,其中最为活跃 ...
- 未来-区块链-IBM:IBM 区块链技术开发社区
ylbtech-未来-区块链-IBM:IBM 区块链技术开发社区 1.返回顶部 1. 开始学习 IBM Blockchain 101:开发人员快速入门指南 这篇快速入门指南适合不熟悉区块链技术,希望快 ...
- cpp 区块链模拟示例(四) 区块链工作量证明
本文主要在之前的区块链原形上添加了工作量证明,并且为后继的交易功能做好准备. 上一个章节我们已经创建了区块链的基本原形,但是区块的哈希计算和加入太过于简单,如果按照这种速度添加区块那么区块链估计一个小 ...
随机推荐
- 机器学习:多项式回归(scikit-learn中的多项式回归和 Pipeline)
一.scikit-learn 中的多项式回归 1)实例过程 模拟数据 import numpy as np import matplotlib.pyplot as plt x = np.random. ...
- Struts2 全局结果集-全局result节点设置,package设置abstract=true的实现
转自:https://blog.csdn.net/u013161278/article/details/41855273 如果我们所有的action均有可能跳到相同的页面,则不妨使用全局result. ...
- [Python Study Notes]物体运动检测
基于opencv的cv2模块实现 ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ...
- Windows安装memcached图文教程(转)
一.下载Memercached For Windows 二.安装步骤 1.解压到指定目录,如:C:\Memcached\memcached-win32-1.4.4-14. 2.用cmd打开命令窗口,转 ...
- day17 14.dao模式介绍
Web的三层架构,不是MVC,Web层,Service层,DAO层. 之前玩的JSP Servlet JavaBean那是MVC模式,那玩意只是表现层的东西. 转账汇款的例子. 说了这么多有啥用啊,一 ...
- Codeforces 56D Changing a String (DP)
题意:你可以对字符串s进行3种操作: 1,在pos位置插入字符ch. 2,删除pos位置的字符. 3,替换pos位置的字符为ch. 问最少需要多少次操作可以把字符s变成字符s1? 思路: 设dp[i] ...
- 使用ServerSocket建立聊天服务器(二)
-------------siwuxie095 工程名:TestMyServerSocket 包名:com.siwuxie095.socket 类名:M ...
- C++面向对象类的实例题目十
题目描述: 编写一个程序,其中有一个汽车类vehicle,它具有一个需要传递参数的构造函数,类中的数据成员:车轮个数wheels和车重weight放在保护段中:小车类car是它的私有派生类,其中包含载 ...
- unity3d 5.6参考手册
http://www.vfkjsd.cn/unity3d/Manual/index.html http://www.vfkjsd.cn/unity/unity3d.html
- 面试题:3年工作经验 已看1 有用 memcache和redis有什么区别
此内容偏中高级,适合有三年经验者. 1. java中wait和sleep有什么区别?多线程条件下如何保证数据安全? 答:最大区别是等待时wait会释放锁(乐观锁),而sleep会一直持有锁 ...