区金年会- 金年会体育 注册即送88元- 官方网站块链技术4:密码学之哈希发布日期:2026-01-15 浏览次数:

  金年会,金年会官网,金年会平台,金年会登录,金年会网址,金年会网站,金年会app,金年会官方网站,金年会体育,金年会数字站,金年会娱乐,金年会体育赛事,金年会体育,金年会最新入口

区金年会- 金年会体育 注册即送88元- 金年会官方网站块链技术4:密码学之哈希

  所以,我们非常需要这样一种电子支付系统,它基于密码学原理而不基于信用,使得任何达成一致的双方,能够直接进行支付,从而不需要第三方中介的参与。

  bitcoin是一种加密货币,密码学在系统中起到了至关重要的作用:防欺骗,工作量证明,交易验证等。密码学本身涉及到非常复杂的高级数学技术,精妙而且难以理解。幸运的是,比特币只用了一些相对简单的广为人知的密码学知识。这里我们简单介绍哈希。

  举一个简单的例子来说明它的用法。譬如学校里以学生名字为索引建了一张表,存储学生的信息。同时希望在查找的时候能够高效率地查找到学生。可以怎么实现呢?(如果以学号为索引,可以一次查找就找到(根据学号的偏移计算);以名字为索引纯粹是举例,名字的问题在于它是字符串,所以需要使用字符串匹配;但是在实际中有很多以名字为索引的情况,譬如Web开发中,表单form的各项一般都有名字,在后台代码实现中便是以名字为索引的)

  如果靠匹配字符串来查找,毫无疑问是非常低效的;所以这个时候的一个做法就是,首先在存储时,对名字进行一次哈希,得到一个数字;然后将名字存在相应数字所对应的位置。在进行查找时,再对希望查找的名字进行一次哈希,得到位置。在算法上,哈希的平均复杂度是O(1)。

  从上面的例子中可以看出哈希函数的一些基本特征。譬如,哈希函数接收各种输入,经过一定的运算,产生一定范围内的输出。上图中红色的线指出了哈希函数的一个重要特征,collision冲突。因为理论上,哈希函数可以接收所有的字符串作为输入,从输出的话,一般会限定一个范围,所以,极有可能有两个或多个输入产生同一个输出,这个时候就称为产生了一个冲突。常见的哈希算法如取模运算。譬如 x mod 100,会将101, 1001,和1 都哈希到1这个位置。(至于为何明知道有冲突还要用哈希,想一个例子,譬如有一个公司有200名员工,存储员工信息的表只需要200个项就够了;但是如果是以身份证号为索引,身份证号的空间范围是很大的(10^20左右),但是输入总共只有200个,也即非常稀疏,通过哈希可以将输出限制在200左右,比较好的哈希函数能够尽量避免冲突,或者冲突非常的均匀。)

  加密哈希是哈希函数的一种,它具有某些属性,使其适用于加密。通过加密哈希,它将任意大小的数据映射到固定大小的位串(散列),并被设计为单向函数,即一个不可逆的函数。从理想的加密散列函数输出重新创建输入数据的唯一方法是尝试对可能的输入进行暴力搜索,以查看它们是否产生匹配,或使用匹配哈希的彩虹表。布鲁斯施奈尔称单向散列函数是“现代密码学的主力”。输入数据通常称为消息(Message),输出(散列值或散列)通常称为消息摘要或简称为摘要(Digest)。

  4. 对消息进行小的更改便能引起哈希值的巨大改变,以使新哈希值看起来与旧哈希值不相关

  常见的哈希函数都满足这个特性。(只要计算过程中没有引入随机数/调度,应该都满足?)

  hiding就是知道哈希的结果不能倒推输入。简单来说,譬如 x mod 100这样的哈希函数,如果结果是1,那么x可能是1、101、201等无穷的数。从SHA族算法,从结果完全得不到输入的任何信息。

  当两个输入产生同一个输出,就发生了冲突。这里的抗冲突不是说肯定不会冲突,由鸽笼原理很容易看出,只要定义域大于值域,肯定会有冲突的。哈希函数的抗冲突指的是,虽然冲突就在那里,那就是找不到——或者说在可接受的时间内找不到。

  接下来,我们重点讨论三个特点:抗冲突、隐藏以及puzzle friendliness,以及它们的应用。

  注意这里说的是不可能找到,而不是说不存在。实际上根据鸽笼原理,对于输出是256比特的SHA-256,那么只要找到2^256+1的输入,肯定可以找到至少两个值有冲突。

  上面的方法是肯定可以找到冲突,把复杂度降低一点,利用生日攻击原理,如果随机挑选2^130+1的输入,有99.8%的概率可以找到冲突。

  生日悖论:生日悖论是指在不少于 23 个人中至少有两人生日相同的概率大于 50%。例如在一个 30 人的小学班级中,存在两人生日相同的概率为 70%。对于 60 人的大班,这种概率要大于 99%。这个数学事实十分反直觉,故称之为一个悖论。生日悖论的数学理论被应用于设计密码学攻击方法——生日攻击。

  1* \frac{364}{365}*\frac{363}{365}*\frac{362}{365}...*\frac{365-n+1}{365}

  但即使如此,找到一个冲突所需的时间也是不能接受的。如果每秒中可以计算10,000次哈希,将会需要10^27年来计算2^128次哈希。打个比方,即使人类制造出的所有计算机从宇宙起始的时候开始计算,那么到现在,发现冲突的概率大概是2秒之内地球被陨石撞击毁灭的概率。好,开始数,1,2。地球并没有被毁灭,看样子,冲突也还没有被找到。

  从这个分析也可以看出,为了让哈希算法更安全,输出尽可能要长一点。譬如,如果输出是32位,那么2^16的计算还是很容易做的。

  另外,关于哈希算法的抗冲突性,到目前为止,没有哪个哈希算法被证明是抗冲突的,只是人们一直在努力找到针对算法的冲突方法,有些找到了如MD5,有些一直没有被找到。所以,目前为止我们相信它们是抗冲突的。

  对于抗冲突性的哈希函数而言,如果两个输入x和y不同,那么就可以认为H(x)和H(y)不同——否则的话,就违反了抗冲突性。

  这个性质就可以做信息摘要。考虑2015年的xcode后门事件,因为国内的开发者从苹果官网下载xcode开发框架速度太慢,所以一些公司的开发人员直接从百度云上下载了某些人“好心”提供的版本。腾讯的安全实验发现很多app出现异常流量后发现源头在于使用的xcode,即使开发人员本身写的代码是正确的,经过篡改的xcode可以将恶意代码链入到app中。所以带来的一个问题是,当我们下载开源的软件使用时,怎么可以保证下载到的软件是官方的而不是经过第三方恶意修改过的呢?

  这是mysql的下载页面,可以看到在提供下载链接的同时,提供了MD5散列摘要。如果想要保证安全,可以在第三方下载软件之后,使用同样的算法做一次散列,如果相同,可以放心使用。

  Hiding的意思是如果有哈希函数的输出y,那么不可能找到x,使得h(x)=y。

  关于hiding的含义前面已经解释过。现在的一个问题是,如果输入值本身是有限的,譬如在一个掷硬币的游戏中,如果扔出来head,那么就计算“head”的哈希值;如果扔出来tail,那么就计算tail的哈希值。那么在一次投掷过后,公布哈希值,能知道这次投掷的结果吗?

  这个问题的特点是输入值的空间太小,如果想要知道输入是什么,只需要遍历一遍,把所有可能的值计算一下,然后进行比对就行。譬如在这里,只需要算两个值,那么肯定可以知道投掷的结果。所以也就失去了hiding的特点。

  答案就是通过对简单的head和tail后面跟上一个随机性较强的串r,这样就能实现hiding。譬如,后面跟上长度为256bit的串,这样因为r的随机性足够强,即使head和tail很简单,也有足够的隐藏性。

  commitment(承诺)。承诺的场景,譬如,世界杯预测结果,每个人都把自己预测结果放在信封里,并且封上信封,放在桌上。这相当于做出了一个承诺。然后世界杯结束后,大家拆开信封,看看当初谁预测得最准确。

  com := commit(msg, nonce), nonce是一个随机的秘密的数字(譬如256位);然后公开com;相当于把公布了一个密封的信封;大家都知道做出了承诺,但是具体值是什么还没有公开

  verify(com,msg,nonce),如果要检验,则用户提供原始的msg和nonce,通过同样的方法计算,看com是否和commit计算出来的结果相同

  对于每一个可能的n位输出y,如果k是随机性很强的值(譬如长度为256位的随机二进制串),那么找到一个合适的x使得H(kx)=y是不可能显著地低于2^n的时间复杂度。

  这个特点强调的是,如果给定特殊的哈希结果y,并且输入中有一部分随机性很强k,那么找到输入的另一个部分x使得哈希的结果等于y,那么就只能依靠暴力搜索。

  SHA-2下包括六个不同的算法标准:SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224、SHA-512/256。这些不同的算法使用不同生成摘要的长度 、循环运行的次数,但算法的基本结构是一致的。现在已知SHA-2容易受到长度扩展攻击,所以推荐使用SHA-3来取代它。

  对于任意长度的消息,SHA256都产生256bit长的哈希值,也即32字节,或者64位的16进制数,或者8个8位的16机制数 。:)

  看一下,分别是8个16进制数,所以总共有256位,这个就叫做初始向量(IV)。这8个数是前8个素数取平方根,前32位小数。最终生成的哈希值也是这么长,所以,每一轮的计算就是如上图所示,更新这8个值。

  每一轮计算64次。在上图中可以看到,除了A~H外,有两个输入,分别是w_{t}和k_{t}。也即每一轮中有64个w,以及64个k。每个w长度为32bit,也即4个字节。64个w来自于哈希函数的输入,也即,对于输入,不论长短,长的就分成每512bit一个块(64个字节),短的补足512bit。这64个字节构成了前16个w,后面的48个w通过前面的16个生成。

  关于短的输入如何补足也有一些细节,在输入末尾进行填充,使输入长度在对512取模以后的余数是448。填充的具体过程:先补第一个比特为1,然后都补0,直到长度满足对512取模后余数是448。需要注意的是,信息必须进行填充,也就是说,即使长度已经满足对512取模后余数是448,补位也必须要进行,这时要填充512个比特。因此,填充是至少补一位,最多补512位。为什么余数是448呢?因为,还有需要有64位的数据表示原始输入的长度,加上这64bit的长度信息448+64=512,刚好512位。

  利用puzzle-friendliness的工作量证明,也即,要求生成一个新区块时,哈希值一定要是以一定数量的连续的0开始的;

  对每个区块的内容进行哈希,后面的区块相当于一直在对前面的区块进行哈希,所以一般来说,如果一个区块之后如果跟上其他6个区块之后,一般认为该区块的内容已经被公认了,不可更改。