时间:2018-05-15
(书接上文)
现在,我们给数学家提出一个要求:请设计一个算法,将任何一条信息,不论长短,都计算出一个唯一的“数字指纹”与它对应。但有两个附加条件:一、指纹的长度必须固定;二、只能从“原始信息”计算出“指纹”,谁也无法从“指纹”反向计算出“原始信息”。
这个要求,看似很过分,但是难不倒数学家。1993年,美国国家安全局发布了SHA算法,全称是Secure Hash Algorithm,中文一般翻译为“安全散列算法”或者“安全哈希算法”,这个名称估计把你吓到了,听着特学术(我有时候会听人说“嘻哈算法”,忍不住偷笑一下,各位千万别读错)。
Hash这个词没有对应的中文意译词,如果让我来意译的话,我会翻译为“数字摘要算法”,基本上能表达该算法的含义,就是从目标对象中提取出一个特征摘要,好像人的指纹一样。
SHA算法从1993年发布它的第零代,一直到2015年发布第三代,二十二年间已经升级了四次。比特币用到的是第二代算法,简称为SHA-256算法,这里的“256”表示,由这个算法生成的指纹长度固定为256比特。大家可以很容易在网上找到在线生成SHA-256指纹的网页,这个算法是公开的,谁都能用,例如,“钱”字的SHA-256指纹是:
0000111010111000011000111100011110001101101000111110001110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
“A支付5元钱给B”的SHA-256指纹是:
1111011110111011001010011011101011011111000001011101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
大家看到,不论原始信息有多长,生成的指纹都是一样长的。而且这个指纹还有两个显著特点:一、原始信息只要改变一点点,哪怕只改动一个数字,整个指纹就会发生巨大的变化,毫无规律可循;二、截至本文写作时,世界上还没有任何公开的方法可以从指纹反向计算出原始信息,普遍认为理论上无法破解。
不过,在实际的使用中,256位的二进制数据太长了,使用起来极不方便,还很容易看花眼。于是,指纹通常用十六进制来显示,反正二进制到十六进制是一一对应的。
“钱”的十六进制指纹是:
0eb863c78da3e38b6b92d1f3999566e5d8e17a6f700a112c8993cf6bfc48f70b
“A支付5元钱给B”的十六进制指纹是:
f7bb29badf05d41e60b1036d749f134a901c7a97daef7a1fe4e1e14471bd4833
这样看起来就简洁多了,我们可以试一下把“5元钱”改为“6元钱”,看看指纹的变化有多大,下面是改后的指纹:
1d48da12b0fb29efe6f690185922f96d259bd887343735898bfc3901a83b58c3
看到了吧,仅仅改动了一个数字,但指纹几乎没有一位是相同的。这就是SHA算法的神奇之处,也确保了指纹没有规律可循,无法被反向破译。
有了数字指纹,就可以解决第一个问题:确保记账信息的完整性。怎么做?很简单,我们只要做出一个规定,任何发出信息的一方,必须同时发出原始信息的指纹。那么收到信息的一方只需要用公开的SHA-256算法把原始信息也生成一个指纹,和收到的指纹比对一下,如果一致,就说明收到的信息是完整的;如果不一致,说明收到的原始信息由于某种原因被修改过了,这个原因可能是数据传输过程中的错误,也可能是被人篡改了等等。
那会不会有一种巧合,原始信息和指纹都因为某些传输错误发生了改变,恰好错误的指纹数据就是出错后的原始信息指纹,也就是负负得正了?这事当然不是绝对的不可能,但是从概率上来说,想要自然发生,大概等到宇宙灭亡了也不会发生一次,概率已经低到可以彻底忽略。
不过,你可能也想到了,还有一种可能性,就是黑客恶意篡改。因为SHA算法是公开的,如果有一个黑客拦截了原始信息和指纹,他把原始信息修改掉,比如把“A支付5元钱给B”改为“A支付5元钱给C”,同时生成新的指纹发送给你。这该怎么办呢?这就是我们要解决的第二个问题:如何确保信息的真实性?解决这个问题,等于也解决了信息发送方想抵赖的问题。
解决第二个问题的关键就是给指纹加密,但是,这种加密还不能是我们在谍战剧里看到的那种电报加密的方式。大家不妨回忆一下看过的谍战剧,我地下工作者收到一封电报,上面写着2352,于是他从书架上拿出一本书,翻到第23页,再数到第52个字,写着一个“撤”字。这就是组织上通知这位同志马上撤退,有人叛变了。这种加密方式的坏处在于,只要敌人也掌握了密码本,不但可以破译电报,还能发送假电报钓鱼,原因就在于加密和解密的方法是完全一样的,能解密就能加密,所以,这种加密方法被叫作“对称加密”,解密的过程只不过是加密的逆过程而已。
“对称加密”用在我们想要的去中心化账本系统中就不好使了,因为我们既要让网络上的每一个信息接收者能够解开密文知道原始信息,又要让黑客即使拿到密文也只能干瞪眼,无法篡改密文。
个中关键,在于加密和解密的方法必须不一样。所以,就要求数学家搞出一种全新的加密算法,这种算法是非对称的,加密、解密不是互逆的过程。
能不能搞出这样一个巧妙的加密算法呢?当然是能的,否则就不会有比特币了嘛。下面我用一个简化版的非对称加密算法模拟一下我们想实现的效果。
原始信息是一组数字:269。
?
现在,我用一种只有我自己才知道的加密算法得到一个密文:24479。
然后,我把24479告诉所有人的同时,还宣布:解开我这条密文的钥匙就是数字11(后面我们就把这个公开的钥匙称为公钥),任何人只要用24479乘以11,取结果的后三位,就能得到我想要告诉大家的原始信息。不信吗?我们试试看:
24479×11=269269
哇,好有意思,不单后三位,连前三位都是原始信息。我是怎么加密的呢?很简单,我把原始信息乘以91就是密文,而这个91就可以叫“私钥”,我私人的加密钥匙。这样就实现了加密和解密是完全不一样的两种算法。
你可以试试看,用任意一个三位数字乘以91,得到的结果再乘以11,最终得到的结果一定是原始三位数写两遍。例如:218×91×11=218218。
如果用任意一个二位数字乘以91,得到的结果再乘以11,最终得到的结果后二位数字也一定与原始数字相同。例如:18×91×11=18018,至于它背后的数学原理,稍微琢磨一下就能想明白了。
但是请记住,我举的这个例子只是让你体会一下什么叫非对称加密,因为这个例子的算法太过简单,所以知道了公钥是11的人,很容易猜出私钥是91。但是比特币系统采用的算法比这个复杂多了,那个算法确保了任何人即使知道原文、密文、公钥,也无法猜到私钥。也就是说,黑客只能解密,但不会加密,无法修改密文。
(本文原刊《读库1802》,书接上文,未完待续,敬请关注下期)
Copyright © 2018-2020 www.fqcycpa.com 北京峰清诚永会计师事务所(普通合伙) 版权所有 京ICP备14007909号