目录
哈希函数及哈希函数的特性
什么是哈希函数?
哈希函数接受任意的输入x
可以是字符串 数字 或任意类型的任意值
并返回固定长度的值y
这个过程也称为散列或摘要
所以哈希函数有时候也成为散列函数或摘要函数(摘要算法)
常见的哈希函数(哈希算法)
-
SHA-1
-
GOST
-
MD2
-
MD4
-
MD5
-
Panama
不好的哈希函数的例子
-
将任意输入的值作为一个字符串 并转换字符串中每个字符的值为ascII码表的整数值
-
将每个字符对应的ascII码表值相加得到一个整数
-
返回这个整数取模256得到的值(
长度在0-255之间 即长度固定在八位二进制00000000~11111111之间
即这个哈希函数返回的值总是1byte长度的数据
不论我们输入的值是什么
此函数返回的总是一个0~255之间的整数
这是一个合规的哈希函数 但并不是一个优秀的哈希函数
哈希-加密哈希
哈希在计算机领域有很多的用途
比如 HashMap这种数据集合中
这个数据结构实际是根据元素的hash值决定将数据存放到内存中的哪个位置
或者在数据库分库分表的场景下
根据键的hash值觉得一条数据应该存储在那个库/表 或该从哪个库/表查找这条数据
有很多不同的哈希函数 他们不同的特性决定了他们适用的领域
在区块链领域 会使用哈希函数进行加密哈希
加密哈希的特性
-
collison-free无碰撞的(抗碰撞的)
-
hidding隐藏的
-
puzzle-friendly谜题友好
无碰撞或抗碰撞的collison-free
如果对于一个哈希函数H(x)
如果:
x≠y
H(x) == H(y)
collison-free所描述的特性即
如果我通过H(x)得到一个哈希值 那么对于其他人而言使用不同的输入得到一个相同的哈希值应该是非常困难的
碰撞的例子
以前文说的不好的哈希函数作为例子
如果我们将"ATTACKATDAWN"作为输入最终得到的值将为 77
如果使用"SIT DOWN###MEOW."作为输入得到的值也将是77
哈希碰撞是不可避免的
哈希函数的入参可以是任何可能的数据 可以将这个数据集合看作是无限大的
但是因为哈希函数的定义(固定长度的返回值)
他只能将入参映射到相对较小的数据集合中
这种从无限到有限的映射必然会发生重复的情况
所以所谓无碰撞或抗碰撞 只是说一个哈希值的碰撞能否在合理的时间范围内被发现
如果哈希值的取值范围足够大
并且构建哈希值的算法合理让生成的值看起来是随机的
这就可以做到 (至少难以暴力破解)
哈希函数的漏洞
如果一个哈希函数生成的值
可以以任何比暴力破解更快的方式寻找到碰撞值
则可以说这个哈希函数是有漏洞的
但一个哈希函数根据用途可能并不需要抗碰撞这一特性
所以可能一个有漏洞的哈希函数依然是被广泛使用的
使用哈希作为消息摘要
如果我们使用的哈希函数是具有抗碰撞特性的
如果H(x) = H(y)
则可以较合理的相信x=y
隐藏的 Hiding
指隐藏原始信息
不能从结果倒推出最初的哈希函数输入值
即 哈希函数应该是单向的
一个不具备隐藏性的哈希函数的例子:
如果我们知道H(x)生成哈希值的算法
知道最终得到的哈希值为42
那么我们可以很容易的倒退出x为41
所以这里的H(x)不是一个具备隐藏性的哈希函数
提交方案 CommitmentScheme
为了理解hidding这一特性 可以想象这样一个例子
a与b打赌
a猜测 一个比特币的价值会在今年突破10000美元
但他不想在赌约兑现之前让b知道这一信息
那么a可以通过与b约定的哈希函数H(x)生成一个哈希值:
x=“一个比特币的价值会在今年突破10000美元”
H(x) = y
让b持有y即可
在兑现赌约 即判断谁是这场打赌的赢家时 a提供x →"一个比特币的价值会在今年突破10000美元"
b计算哈希值H(x)是否等于y 即可知道当时建立赌约时a生成哈希值使用的信息是否是"一个比特币的价值会在今年突破10000美元"
以此过程 a和b在信息不完全传达的情况下完成了一次打赌
这个例子所讲的情况如果想要成立 就需要H(x)具备 抗碰撞性以及隐藏性
如果不具备抗碰撞性
a就可以使用一个与建立赌约时得到哈希值y提供的x不同的信息(碰撞值)去兑现赌约
如果不具备隐藏性
b就可以在得到哈希值y后倒推得出a建立赌约使用的信息x
上面打赌这个例子的过程类似区块链领域使用的CommitmentScheme即提交方案
com = commit(m,nonce)
m为原始信息 nonce为一个只使用一次的随机值 生成的com可以理解为一个哈希值
verify(com,msg,nonce)
验证过程 需要提供哈希值com 以及生成此com所使用的m和nonce
如果m和nonce生成的哈希值等于com则验证通过
如果commit方法使用的哈希函数是抗碰撞且有隐藏性的
那么就不太可能找到m’/nonce’ (m’≠m nonce’≠nonce)
使得commit(m’,nonce,)=commit(m,nonce)
也就保证了提交方案的有效性
这里添加了随机值nonce可以理解为在算法commit不变 原始信息m不变的情况下
为了得到不同的哈希值com的一种处理方式
nonce不具备现实意义并且只使用一次(类似密码撒盐哈希再入库的过程)
谜题友好 PuzzleFriendliness
简单来说 谜题友好即
没有任何捷径生成特定的或部分特定(以某值开头或以某值结尾 大于某值或小于某值)的哈希值
生成特定哈希值只能通过不断尝试 除此之外没有任何其他方式
这种特性称为谜题友好的
工作证明与谜题友好特性
-
a需要在获得奖励之前证明它完成了一些工作
-
所以奖励的发放者要求a找到一个值x 有H(x)=0
-
a为了找到x只能尝试H(x)的不同输入
即H(x)必须是谜题友好的
前文提到的不好的哈希函数是谜题友好的吗?
因为算法生成的哈希值来自字符串每个字符对应ascII码表的索引值的和
只需要简单调整输入的字符串内容就可以得到特定的哈希值
比如替换一个"A"为"B"就可以使得最后得到的哈希值增加1
反之就减少1
前文作为例子的哈希函数是不具备谜题友好性的
比特币使用的哈希函数
-
SHA-256
256位输出
具有抗碰撞性 隐藏性 谜题友好性
-
RIPEMD-160
160位输出
此文为个人学习笔记
原始内容来自b站转载视频
原视频系列标题:
原视频链接:
感谢原内容作者
转载视频翻译多数为机翻 此文可能某些地方词不达意或翻译错误 若有错误还请指正 感谢