每天进步一点点:HASH以及HMAC
今天早些时候的帖子提到一个STEEM的菠菜应用Magic Dice,并且我说它解决了透明性和公平性等问题,简单来讲,就是庄家(服务提供者)无法出老千(控制开奖结果)。
(图源 :pixabay)
在更进一步介绍它如何实现无法出老千这个问题之前,我们先来简单看看和密码学相关的两个概念。因为我不是专家,所以就粗略介绍一下,太深入的讲解就会贻笑大方的。
HASH
Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。
——来自百度百科Hash (散列函数)
这个东西有什么用呢?它的用途之一就是防篡改(其它用途我们暂不讨论)。在我70大寿(Reputation 70)的时候,曾经搞过一次奖励为100个STEEM的抽奖,为了证明抽奖的公平性,中奖数字是已HASH的形式发布到抽奖活动贴里,这样开奖时,公布生成中奖数字的代码,就可以证明我没有作弊。
比如,活动贴中我公布了如下HASH
💰一等奖抽奖密码: fcc420adc5de61752db7ecfa837564f45c47852b
💰二等将抽奖密码: 69bc4460aaab914869fa8209da3d06f1494ea62d
💰三等将抽奖密码: 0e756e1b5d7dc2bab3d86b3d490d3801b904f929
而开奖贴我公布了如下代码(其中sha1是hash所使用的算法,我们还可以使用MD5、SHA256等等):
hashlib.sha1(bytes('一等奖中奖密码:6', 'utf-8')).hexdigest()
'fcc420adc5de61752db7ecfa837564f45c47852b'
hashlib.sha1(bytes('二等奖中奖密码:8', 'utf-8')).hexdigest()
'69bc4460aaab914869fa8209da3d06f1494ea62d'
hashlib.sha1(bytes('三等奖中奖密码:1', 'utf-8')).hexdigest()
'0e756e1b5d7dc2bab3d86b3d490d3801b904f929'
如果我想作弊,那么必须用不同的内容,生成相同的HASH,那几乎是不可能的。比特币以及STEEM中签名算法,都用到了HASH函数,这也是防篡改的应用之一吧。
HMAC
在说HMAC之前,我们在回到HASH上来。以网站常用与身份验证MD5为例,网站一般不保存用户密码,而是保存用户密码的HASH(MD5值),当用户登录授权时,网站必对用户密码以及数据库中的MD5值,判断是否是合法用户。
但是这样做存在一个风险,假设网站包含用户密码MD5值的数据库泄露,那么我用常见密码字典生成一个MD5字典,并于网站数据库中的值进行比对,这样就有很大的可能碰撞出一大堆用户名密码的明文。(彩虹攻击)
那么如何防止这种情况呢?简单的办法是加一个混淆量,比如之前的代码:
hashlib.sha1(bytes('一等奖中奖密码:6', 'utf-8')).hexdigest()
可以改成
hashlib.sha1(bytes('mypassword'+'一等奖中奖密码:6', 'utf-8')).hexdigest()
但是一种更简单更安全的方式是使用HMAC,简单来讲,可以理解为带密码的HASH。
所以上述代码可以改写成:
hmac.new(b'mypassword', bytes('一等奖中奖密码:6', 'utf-8'), digestmod='SHA1').hexdigest()
想了解更多详情的,可以移步https://en.wikipedia.org/wiki/HMAC,总之我是看不懂啦。
(图源 :pixabay)
就这样了,再多说就要暴露我其实啥也不懂的事实了,言多必失啊。
https://steemit.com/~witnesses type in
oflyhigh
and click VOTE
Vote @oflyhigh via Steemconnect
Thank you!
Thank you so much for participating the Partiko Delegation Plan Round 1! We really appreciate your support! As part of the delegation benefits, we just gave you a 3.00% upvote! Together, let’s change the world!