哈希函数的第二个特性便是隐秘性了。假设有一个哈希函数 h(x)=y,只要我们在这个函数里面输入一个x,那么就可以得到一个哈希值 y。如果不理解这个函数的朋友,你可以把这个哈希函数理解成一条长长的山坡,然后我们手里有一个石块 x,当我们把手中的石块从山坡上滚去的时候,就相当于这个哈希函数开始计算结果了。过一会后,我们抛出去的那个石头就滚到山脚下了,因为在山坡上滚动的过程中会发生多次碰撞,所以最后那块石头就会变的更圆一些,棱角会被磨掉一些,这块石头就是哈希函数输出的 y。
那这跟隐秘性有啥关系呢?现在员外问你,如果在一开始抛石头的时候,你是可以看到自己手中的石头是个什么样子的,而且你也拍照保存了,等到了山脚下,你同样可以看到这块石头变成了什么样子,同时你也拍照了。但是如果在一开始你是没有看到石块是个什么样子,然后员外让你根据山脚下的石头推算出原先在山顶的石头的模样,你推算的出来吗?答案是不可能的。
真的不可逆吗?
对于上面这个例子来看是不可能的,因为这个哈希函数的计算方式实在是太复杂,那如果用一个特别简单的哈希函数呢?哈希函数的隐秘性还存在吗?
现在我们做一个简单的哈希函数,掷骰子。规则如下:员外把骰子🎲放到桌子上,假设这枚骰子面朝上的点数是 X ,然后把这枚骰子推到地上,这个过程是哈希函数 H(X),然后骰子落到地上面朝上的点数是 Y。虽然这其中没有必然的因果联系(实际中是有的),但是如果员外指着地上的骰子问你,开始时候在桌面上骰子的点数是几?那么你是有1/6的机会猜对的,这就是哈希函数一个可逆的过程,同时这个哈希算法也几乎没有什么隐秘性可言了。
应用
这里要介绍的一种广泛应用便是——托管(Commitment)。也许很多同学对“托管”这个专业名词很陌生,“托管”可以理解为:
假设有一群人和你一起围坐在一张桌子边,你将一个数字放入信封中并封闭信封,将信封公开地放在桌子上。这就是说,你把这个数字托管给了这个信封。大家都可以看到这个信封,但你并没有打开信封,所以里面的数字对其他人而言是未知的。之后你可以打开信封取出里面的数字,但目前它是被密封的。
由此可见,秘密地保存一个数,然后再次取出这个数,这就是我们要数字化地重复的过程。因而,我们需要做两件事情——托管与验证。托管的过程,是将我们消息(message,msg)输入托管函数(commit()),托管函数将会对消息进行加密,从而得到一个公钥(common key)和一个私钥(private key)。公钥就像是信封,它被公开就是把信封放到桌子上的过程。
验证的过程,是将持有的公钥、私钥和消息输入验证函数(verify()),验证函数将返回公钥和私钥是否与消息相匹配,也就是说输入的公钥和私钥是否是和现有输入的消息的加密结果,或者说现有输入的消息是否是公钥和私钥所加密的原文。这就像打开信封的过程;对于一个信封而言,只有当初封装入数字的你才能打开它,因为你知道里面真正的数字且持有正确的私钥(可以看做打开信封的正确方式)。
网友评论