今天早些时候的帖子提到一个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!
This page is synchronized from the post: 每天进步一点点:HASH以及HMAC