1.3.1 区块链中的加密算法——Hash算法(更新)

  为了为保证存储于区块链中的信息的安全与完整,区块链中使用了包含密码哈希函数和椭圆曲线公钥密码技术在内的大量的现代密码学技术,同时,这些密码学技术也被用于设计基于工作量证明的共识算法并识别用户。

  在前边的文章中已经系统的讲述了密码学中的哈希算法,在本节,将会给大家介绍Hash算法在区块链中的应用!



概念回顾:

  哈希函数:是一类数学函数,可以在有限合理的时间内,将任意长度的消息压缩为固定长度的二进制串,其输出值称为哈希值,也称为散列值。

  以哈希函数为基础构造的哈希算法,在现代密码学中扮演着重要的角色,常用于实现数据完整性和实体认证,同时也构成多种密码体制和协议的安全保障。

  碰撞是与哈希函数相关的重要概念,体现着哈希函数的安全性,所谓碰撞是指两个不同的消息在同一个哈希函数作用下,具有相同的哈希值。

  哈希函数的安全性是指在现有的计算资源(包括时间、空间、资金等)下,找到一个碰撞是不可行的。



区块链中的加密算法······即将开始

        噔噔、噔···噔···!



比特币中的加密算法:

  在比特币系统中使用了两个密码学Hash函数,一个是SHA256 RIPEMD160

其中:RIPEMD160主要用于生成比特币地址,我们着重分析比特币中用得最多的SHA256算法。

  

SHA历史介绍:
    SHA256属于著名的SHA家族一员。SHA(Secure Hash Algorithm,安全哈希算法)是一类由美国国家标准与技术研究院(NIST)发布的密码哈希函数。正式名称为SHA的第一个成员发布于1993年,两年之后,著名的SHA-1发布,之后另外的4种变体相继发布,包括SHA224、SHA256、SHA384和SHA512,这些算法也被称作SHA2。SHA256算法是SHA2算法簇中的一类。对于长度小于264位的消息,SHA256会产生一个256位的消息摘要。SHA256具有密码哈希函数的一般特性。

  

  那么比特币中的SHA256又是何方神圣?它的设计原理是什么?代码又如何实现呢?

            下面让我娓娓道来·····



  SHA256又是何方神圣?

  SHA256是构造区块链所用的主要密码哈希函数。无论是区块的头部信息还是交易数据,都使用这个哈希函数去计算相关数据的哈希值,以保证数据的完整性。同时,在比特币系统中,基于寻找给定前缀的SHA256哈希值,设计了工作量证明的共识机制;SHA256也被用于构造比特币地址,即用来识别不同的用户。

  SHA256是一个Merkle-Damgard结构的迭代哈希函数,其计算过程分为两个阶段:消息的预处理和主循环。在消息的预处理阶段,主要完成消息的填充和扩展填充,将所输入的原始消息转化为n个512比特的消息块,之后对每个消息块利用SHA256压缩函数进行处理。这个计算流程是一个迭代计算的过程,当最后1个消息块(第n块)处理完毕以后,最终的输出值就是所输入的原始消息的SHA256值。

  在比特币系统中,SHA256算法的一个主要用途是完成PoW(工作量证明)计算。按照比特币的设计初衷,PoW要求钱包(节点)数和算力值大致匹配,因为需要通过CPU的计算能力来进行投票。然而随着人们对SHA256的计算由CPU逐渐升级到GPU,到FPGA,直至到ASIC矿机,这使得节点数和PoW算力也渐渐失配。解决这个问题的一个思路是引入另外的一些哈希函数来实现PoW。

  scrypt算法最早用于基于口令的密钥生成,该算法进行多次带参数的SHA256计算,即基于SHA256的消息认证码计算,这类计算需要大量的内存支持。采用scrypt算法进行PoW计算,将PoW计算由已有的拼算力在一定程度上转化为拼内存,能够使得节点数和PoW的计算力的失配现象得到缓解。莱特币就是采用scrypt算法完成PoW计算的。

  SHA3算法是2012年10月由NIST所选定的下一代密码哈希算法。在遴选SHA3算法过程中人们提出了一系列的候选算法,包括了BLAKE、Grostl、JH、Keccak、Skein、ECHO、Luffa、BMW、CubeHash、SHAvite、SMID等,最后胜出的是Keccak算法。达世币(DASH,原名暗黑币,DarkCoin)定义了顺序调用上述11个哈希算法的X11算法,并利用这个算法完成PoW计算。同样,由于采用了X11算法,使得节点数和PoW的计算力能够保持一定程度上的匹配。

设计原理

  下面介绍SHA算法计算消息摘要的原理:

  对于任意长度(按bit计算)的消息,SHA256都会产生一个32个字节长度数据,称作消息摘要。当接收到消息的时候,这个消息摘要可以用来验证数据是否发生改变,即验证其完整性。在传输的过程中,数据很可能会发生变化,那么这时候就会产生不同的消息摘要。

  SHA算法有如下特性: 
  1. 不可以从消息摘要中复原信息; 
  2. 两个不同的消息不会产生同样的消息摘要。

  一、术语和概念

  (一)位(Bit),字节(Byte)和字(Word)

  SHA始终把消息当成一个位(bit)字符串来处理。本文中,一个“字”(Word)是32位,而一个“字节”(Byte)是8位。比如,字符串“abc”可以被转换成一个位字符串:01100001 01100010 01100011。它也可以被表示成16进制字符串:0x616263.

   二、SHA256算法描述

  (一)补位

  信息必须进行补位,以使其长度在对512取模以后的余数是448。也就是说,(补位后的消息长度)Q2 = 448。即使长度已经满足对512取模后余数是448,补位也必须要进行。

  补位是这样进行的:先补一个1,然后再补0,直到长度满足对512取模后余数是448。总而言之,补位是至少补一位,最多补512位。以信息“abc”为例显示补位的过程。 
   
  原始信息:01100001 01100010 01100011

  补位第一步:0110000101100010 01100011 1

  首先补一个“1”

  补位第二步:0110000101100010 01100011 10…..0

  然后补423个“0”

  我们可以把最后补位完成后的数据用16进制写成下面的样子 
  

  61626380 0000000000000000 00000000

  00000000 0000000000000000 00000000

  00000000 0000000000000000 00000000

  00000000 00000000

  现在,数据的长度是448了,我们可以进行下一步操作。

  (二)补长度

  所谓的补长度是将原始数据的长度补到已经进行了补位操作的消息后面。通常用一个64位的数据来表示原始消息的长度。如果消息长度不大于2^64,那么第一个字就是0。在进行了补长度的操作以后,整个消息就变成下面这样了(16进制格式) 
  

  61626380 0000000000000000 00000000
  00000000 0000000000000000 00000000

  00000000 0000000000000000 00000000

  00000000 0000000000000000 00000018

  (三)使用的常量

  在SHA256算法中,用到64个常量,这些常量是对自然数中前64个质数的立方根的小数部分取前32bit而来。这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

  该算法使用了六种基本逻辑函数,由64 步迭代运算组成。每步都以256-bit 缓存值ABCDEFGH 为输入,然后更新缓存内容。 
  每步使用一个32bit 常数值Kt 和一个32bit Wt。

  (四)六种基本逻辑函数

        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) 

  其中 x、y、z皆为32bit的字。 
  ROTR^2(x)是对x进行循环右移2位。

  运算逻辑,如图所示:

  (五)计算消息摘要

  基本思想:就是将消息分成N个512bit的数据块,哈希初值H(0)经过第一个数据块得到H(1),H(1)经过第二个数据块得到H(2),……,依次处理,最后得到H(N),然后将H(N)的8个32bit连接成256bit消息摘要。

  I、哈希初值H(0)

  SHA256算法中用到的哈希初值H(0)如下

     H(0)0 = 6a09e667
        H(0)1 = bb67ae85
        H(0)2 = 3c6ef372
        H(0)3 = a54ff53a
        H(0)4 = 510e527f
        H(0)5 = 9b05688c
        H(0)6 = 1f83d9ab
        H(0)7 = 5be0cd19

  注:这些初值是对自然数中前8个质数3、5、7、11等的平方根的小数部分取前32bit而来。

II、 计算过程中用到的三种中间值

    1、64个32bit字的message schedule标记为w0、w1、…、w63。
    2、8个32bit字的工作变量标记为a、b、c、d、e、f、g。
    3、包括8个32bit字的哈希值标记为H(i)0、…、H(i)7。

III、 工作流程

  原始消息分为N个512bit的消息块。每个消息块分成16个32bit的字标记为M(i)0、M(i)1、M(i)2、…、M(i)15然后对这N个消息块依次进行如下处理

            For i=1 to N
        1)   For t = 0 to 15
                     Wt = M(i)t
                 For t = 16 to 63 

                     Wt = SSIG1(W(t-2)) + W(t-7) + SSIG0(t-15) + W(t-16)
         2)  a = H(i-1)0
                b = H(i-1)1
                c = H(i-1)2
                d = H(i-1)3
                e = H(i-1)4
                f = H(i-1)5
                g = H(i-1)6
                h = H(i-1)7
         3)For t = 0 to 63
                    T1 = h + BSIG1(e) + CH(e,f,g) + Kt + Wt
                    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

           4)H(i)0 = a + H(i-1)0
                 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

  对N个消息块依次进行以上四步操作后将最后得到的H(N)0、H(N)1、H(N)2、…、H(N)7串联起来即可得到最后的256bit消息摘要。

代码实现

I 调用库函数:

  下面的示例计算 data 的SHA256哈希值,并将它存储在 result 中。此示例假定存在一个预定义的常数 DATA_SIZE:

  C#的代码示例:

1 byte[] result;
2 byte[] data = new byte[DATA_SIZE];
3 SHA256 shaM = new SHA256Managed();
4 result  = shaM.ComputeHash(data);

  Java的代码示例:

1 ubyteresult[];
2 ubyte data[] = new ubyte[DATA_SIZE];
3 SHA256 shaM  = new SHA256Managed();
4 result  = shaM.ComputeHash(data);

  SQL的代码示例:

1 SELECT sha2(data,256);

  PHP的代码示例:

1 $result=hash(‘sha256‘, $data);

II 自己编写代码实现

  前面我们已经说明了SHA-256的计算过程,接下来我们将这一过程代码化。同样的首先定义一个上下文的结构。

 1 /** 定义SHA-256哈希操作的内容信息结构体 */
 2 typedef struct SHA256Context {
 3   uint32_t Intermediate_Hash[SHA256HashSize/4]; /* 信息摘要 */
 4   uint32_t Length_High;                         /* 按位计算的信息长度高字 */
 5   uint32_t Length_Low;                          /* 按位计算的信息长度低字 */
 6   int_least16_t Message_Block_Index;            /* 信息分组数组的索引 */
 7   uint8_t Message_Block[SHA256_Message_Block_Size];/* 512位信息分组 */
 8   int Computed;                                 /* 摘要计算标识 */
 9   int Corrupted;                                /* 信息摘要损坏标识 */
10 } SHA256Context;

  实现SHA256Context结构的初始化,为后续的计算过程做准备。

 1 static SHAStatusCode SHA224_256Reset(SHA256Context *context, uint32_t *H0)
 2 {
 3   if (!context) return shaNull;
 4   context->Length_High = context->Length_Low = 0;
 5   context->Message_Block_Index = 0;
 6   context->Intermediate_Hash[0] = H0[0];
 7   context->Intermediate_Hash[1] = H0[1];
 8   context->Intermediate_Hash[2] = H0[2];
 9   context->Intermediate_Hash[3] = H0[3];
10   context->Intermediate_Hash[4] = H0[4];
11   context->Intermediate_Hash[5] = H0[5];
12   context->Intermediate_Hash[6] = H0[6];
13   context->Intermediate_Hash[7] = H0[7];
14   context->Computed = 0;
15   context->Corrupted = shaSuccess;
16   return shaSuccess;
17 }

  接下来实现信息分组的输入,这个函数接受一个字节数组作为下一个消息分组以便进行处理。

 1 SHAStatusCode SHA256Input(SHA256Context *context, const uint8_t *message_array,unsigned int length)
 2 {
 3   if (!context) return shaNull;
 4   if (!length) return shaSuccess;
 5   if (!message_array) return shaNull;
 6   if (context->Computed) return context->Corrupted = shaStateError;
 7   if (context->Corrupted) return context->Corrupted;
 8   while (length--)
 9   {
10     context->Message_Block[context->Message_Block_Index++] =*message_array;
11     if ((SHA224_256AddLength(context, 8) == shaSuccess) &&(context->Message_Block_Index == SHA256_Message_Block_Size))
12       SHA224_256ProcessMessageBlock(context);
13     message_array++;
14   }
15   return context->Corrupted;
16 }

  当然还需要一个消息处理及最终摘要输出的函数,这个函数将返回一个224位或者256位的信息摘要到调用者给定的Message_Digest数组。返回的信息摘要,第一个元素索引为0,最后一个元素索引为27(SHA-2244)或者31(SHA-256)。

 1 static SHAStatusCode SHA224_256ResultN(SHA256Context *context,uint8_t Message_Digest[ ], int HashSize)
 2 {
 3   int i;
 4   if (!context) return shaNull;
 5   if (!Message_Digest) return shaNull;
 6   if (context->Corrupted) return context->Corrupted;
 7   if (!context->Computed)
 8     SHA224_256Finalize(context, 0x80);
 9   for (i = 0; i < HashSize; ++i)
10     Message_Digest[i] = (uint8_t)(context->Intermediate_Hash[i>>2] >> 8 * ( 3 - ( i & 0x03 ) ));
11   return shaSuccess;
12 }



区块链中的哈希指针链

  哈希指针是一类数据结构,除了包含通常的指针外,还包含一些数据信息以及与这些信息相关的密码哈希值,这就使得正常的指针可用于取回信息,哈希指针用于验证信息是否发生改变。区块链就可以看作一类使用哈希指针的链表,如下图所示。这个链表链接一系列的区块,每个区块包含数据以及指向表中前一个区块的指针。区块链中,前一个区块指针由哈希指针所替换,因此每个区块不仅仅告诉前一个区块的位置,也提供一个哈希值去验证这个区块所包含的数据是否发生改变。

哈希指针链

  可以利用区块链去构造一个防篡改的日志系统。在这个系统中,基于区块链的日志节点链表被用来存储数据,链表节点通过哈希指针链接,新节点追加在日志链表的尾部。同时,日志链表的头哈希指针所指向的头节点内容不可改变。若日志链表中的某个节点的数据被篡改,则系统能够检测出来。

  假定攻击者改变了节点k的数据,由于其后继节点k+1存储了节点k的哈希值,由于密码哈希函数的抗碰撞性,通过简单地计算节点k的数据的哈希值,就能发现计算出的值与节点k+1的哈希指针值不一致,于是可以断定节点k或节点k+1的信息被篡改。当然,攻击者可能能够连续改变前一个节点的哈希值来掩盖不同,但这个策略在处理日志链表的头节点时将会失败。特别地,一旦将链表头部的哈希指针存储在不能改变的地方,攻击者将不能改变任何节点而不被发觉。

  因此,若攻击者想在日志链表中的任意位置改变数据,为保持一致性,他必须向表头方向修改所有的哈希指针,最终由于不能改变链表头部而失败。因此,只需单个哈希指针,基本上就能保证整个链表的哈希值的一致性,从而达到防篡改的目的。



        哈哈哈哈哈哈,区块链中加密算法——Hash算法之SHA256算法 到这里就更新完了!

             下一节给大家讲Merkle树,敬请期待·····

Reference:

  1.SHA256代码实现:https://www.cnblogs.com/foxclever/p/8370712.html

  2.SHA256算法介绍:https://blog.csdn.net/wowotuo/article/details/78907380

  3.《区块链技术指南》邹均张海宁唐屹李磊 著

原文地址:https://www.cnblogs.com/X-knight/p/9136455.html

时间: 2024-10-07 04:29:27

1.3.1 区块链中的加密算法——Hash算法(更新)的相关文章

区块链中的密码学(三)-椭圆曲线加密算法分析

在目前密码学的非对称加密算法中,RSA算法依然是一种主流,但是随着比特币中对于一种之前不太流行的算法:椭圆加密算法(ECC)的成功应用后,这种算法得到了很大的关注和普及.有一种说法是中本聪不信任RSA算法,认为美国人在其中留有后门,而据斯诺登的爆料也确实如此.相较RSA,ECC不仅在某种程度上杜绝所谓留有后门的情况,而且加密性能/安全性都有提高.本文就带大家一窥ECC算法的天地. 鉴于ECC算法对数学知识要求比较高,不像RSA依赖于中学数学的水平,ECC用到了许多<近世代数基础>,<初等

Java 实现区块链中的区块,BLOCK的实现

1.区块是区块链的基础单元 区块链由若干个区块组成,区块是区块链的基础单元 2.区块链中区块的基本属性 区块6个属性的说明-Index 区块的索引值,区块链中的唯一键区块6个属性的说明-Timestamp 区块的时间戳,用于区分区块的产生时间区块6个属性的说明-Hash 区块的hash值是整个区块各个内容整体计算出的hash值区块6个属性的说明-Previous Hash 前一个区块的hash值区块6个属性的说明-Data 区块链的数据存储部分,例如比特币是用来存储交易数据区块6个属性的说明-N

区块链中的节点是什么

随着区块链科技的进步,各种形态不同的链展现在大家面前,有些区块链中节点有很多(如以太坊),而有些区块链中的节点又很少(如EOS),今天我们拿第一代区块链比特币来讲. 比特币被设计为一种去中心化的点对点(P2P)网络 如中心化的应用都是由一台服务器集中管理,而去中心化的应用就是由很多台服务器管理存储信息,并且相互验证. 综上所诉的去中心应用中的服务器就是节点 节点的作用 为了确认交易有效性,比特币需要多于一个单独网络的矿工处理交易单,它必须通过"节点"向网络广播.这是交易处理过程的第一步

1.3.2 区块链中的密码学——Merkle 树

在计算机领域,Merkle树大多用来进行完整性验证处理.在处理完整性验证的应用场景中,特别是在分布式环境下进行这样的验证时,Merkle树会大大减少数据的传输量以及计算的复杂度. Merkle哈希树是一类基于哈希值的二叉树或多叉树,其叶子节点上的值通常为数据块的哈希值,而非叶子节点上的值是将该节点的所有子节点的组合结果的哈希值. 如下图所示为一个Merkle哈希树,节点A的值必须通过节点C.D上的值计算而得到.叶子节点C.D分别存储数据块001和002的哈希值,而非叶子节点A存储的是其子节点C.

[老k说区块链]区块链中的共识(1)— 免信任的共识机制

老k,柏链道捷CTO.清华阿尔山区块链研究中心高级工程师,超过17年的系统软件开发经验,在操作系统.编译器.虚拟机和符号执行方面都有实战经验.主持开发多个开眼项目,目前主要从事区块链底层系统开发工作. 这个系列的文章主要谈一下我对区块链中的共识机制的理解,欢迎跟大家一起交流.探讨. 前言 当今区块链的概念和产业已经遍布神州大地,创业言必区块链,在各种咖啡厅中你都可以听到周围的人谈论区块链,大部分从业者对区块链技术的一个认识是它是一个分布式账本技术,更有些人说区块链是各种计算机技术的组合,如P2P

区块链中的RESTFUL链码调用API原理详解

本文适合于熟悉开源区块链技术Hyperledger Fabric,以及希望更高效地使用华为云区块链服务的读者.当然,也欢迎任何对区块链技术有兴趣的读者阅读本文,相信读者们都能从中受益. 2018年2月1日 华为云发布企业级区块链开放平台区块链服务BCS(Blockchain Service),是基于开源区块链技术和华为在分布式并行计算.数据管理.安全加密等核心技术领域多年积累基础上推出的企业级区块链云服务产品,旨在帮助各行业.企业在华为云上快速.高效的搭建企业级区块链行业方案和应用. 如前所述,

1.3.2 区块链中的密码学——椭圆曲线密码算法(ECC)

今天在学椭圆曲线密码(Elliptic Curve Cryptography,ECC)算法,自己手里缺少介绍该算法的专业书籍,故在网上查了很多博文与书籍,但是大多数博客写的真的是...你懂的...真不愧是 '天下文章一大抄' 啊! 雷同不说,关键是介绍的都不是很清楚,是我在阅读过程中.产生的很多疑问无法解决!例如:只来句'P+Q=R',但是为什么等于呢?是根据什么计算出来的呢? 后来查了好久,才发现:这是规定的.是定义!瞬间很是无语! 好了,不吐槽了,为了方便大家对椭圆曲线密码算法有系统的了解,

区块链中的软分叉与硬分叉详解

区块链兄弟社区,区块链技术专业问答先行者,中国区块链技术爱好者聚集地 作者:吴寿鹤 来源:区块链兄弟 原文链接:http://www.blockchainbrother.com/article/29 著权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 说到分叉,我们首先了解一下在软件开发中的分叉是什么? 软件项目中的分叉 软件开发中的分叉指的是:在开源项目中如果有人Fork了一个项目(一个项目分叉为两个项目),然后开发者沿着这个Fork向另外一个不同的方向独立发展这个项目.例如L

区块链中的密码学

区块链概念 区块:可以看做是一页一页的账单,上面记录若干条数据 区块链:可以看做是账本,里面按照时间顺序将若干个账单 每个区块中包含两个最重要的值,自己的hash值,和上一个区块的hash值 详解: 区块链是一串使用密码学方法相关联产生的数据块,每一个区块中包含上一个区块的hash值,用于验证其信息的有效性(防伪)和生成下一个区块 Hash算法 Hash算法:可以将任意数据 生成 固定长度的16进制字符串 常见算法:md5 , sha1 , sha256 , sha512等,都是摘要算法 密码学