作者:cklover

本文首发于cklover知乎专栏,题目:【小白入门】比特币使用的SHA256算法究竟是什么?

 

比特币使用的SHA256算法究竟是什么?

 

都说比特币是加密货币,既然叫加密货币,那么比特币必然和加密技术有关。话虽是这么说,但是加密技术包括的内容很多,那么比特币究竟使用了那些密码学技术呢?我们从整个比特币的设计当中可以看到,在比特币系统里有一个比较重要的加密算法,这就是SHA256算法。

SHA256的中文全称叫做“安全哈希算法”。

所谓的“哈希”是Hash的音译,而Hash就是进行Hash函数的意思。通常来说,Hash函数的运算有一个共同特点。就是不论原始数据有多少位,只要通过Hash运算后,得到结果的长度都是固定的。

概念往往是抽象的,那么下面我们就用一个形象的例子进行说明。如果我们去图书馆借书,就会发现不管是什么图书,书的侧面都会贴着一张便签,便签上通常都有一个与图书对应的编号。为了方便管理,这些编号的长度通常都是一样的。这个情况和Hash函数就非常类似。我们可以把输入Hash函数之前的数据看作是书本,这些书本的字数都不一样,有的有几万字,有的有几十万字。但是一旦这些数据通过Hash函数处理过以后,就全部都变成长度相同的编号了。

而且这些编码必须要满足以下几点要求:

第一、输入Hash函数之前的数据和通过Hash函数处理过后得到的编号必须一一对应。

第二、每一个编号的长度都是固定的。

第三、我们无法通过编号倒推出数据的内容。

Hash函数的类型有很多种,包括SHA224、SHA256、SHA384、SHA512、SHA512/224、SHA512/256等。但是比特币仅选用了SHA256。这个256代表的意思是,数据经过函数运算后得到的结果必须是一个256位的2进制数字。也就是类似这样的结果:“001100……11011”,这其中一共有256位。

在比特币里,为什么要把数据转换成256位的数字呢?其实之所以选择SHA256,主要是为了验证两个文件是否相等。

比如:有一个商业间谍获得了一份重要的商业报告。但是这个间谍害怕这份商业报告在网上传递的过程中被别人截获并进行修改。于是就把这份商业机密进行了处理,通过SHA256运算,生成了一个数值,我们暂且称这个数值为A1。

然后这位间谍就把这份商业报告和A1通过电子邮箱传递了出去,并在邮件里注明了:“为了避免其他人对商业报告进行修改,报告下载完成后,请大家对报告做一次SHA256运算,然后看看这个计算结果和A1是否相符。如果和A1完全一致,那么就意味着这份商业报告没有被其他人动过手脚。如果和A1不同,那么就说明你下载的报告很可能被别人篡改过。”

中本聪在设计比特币的时候之所以选择SHA256,主要是看中了SHA256在验证改动方面有着巨大的优势。因为只要输入数据有微小的区别,通过SHA256计算出来的数值都会有巨大的差距。

比如下面这三句话,原文虽然有微小的不同,但是通过Hash函数处理,就会让SHA256值产生巨大的差异,而且这种差异是毫无规律可循的。

原文1:动静不失,人所易明。

S1: 284c4ddd2e5ef97924cc70e90cd02fd792e3fd62

原文3:动静不失,人所易明

S2:991780940ced6e6f910013f2ba2ac732e23601ef

原文3:动静不失人所易明

S2:62e07ce4d7d529a6268841d521bf882d3b385199

SHA安全加密标准,是至今国际上使用最为广泛的较为安全的压缩算法之一,由美国NIST和NSA两个组织共同开发。此算法于1993年5月11日被美国NIST和NSA设定为加密标准。

那么比特币是如何应用SHA256的呢?

我们拿一个日常情况为例子。

老王最近手头紧,于是找老赵借钱,说等发工资了他就把借的钱还上。借钱自然要写借条了。于是老王就给了老赵写了一张借条:老王今天向老赵借了100元人民币。但是如果单单是一张借条,是非常不安全的。万一老赵日后把人民币三个字改成了美元,又或者在100后加了个万字,那老王岂不是亏大了?

在这种情况下,SHA256算法的价值就会凸显出来了。“老王今天向老赵借了100元人民币。”这条信息的SHA256值是确定的,在发出这条信息的同时,我们再给出SHA256值,那么之后任何的改动都会被发现。

但是只保证了支付信息没有被改动过,也还是不够的。如果老赵自制了很多“老王今天向老赵借了10亿元人民币。”这样的借条。那么老王这辈子恐怕都还不清债了。所以为了确定借条的唯一性,我们还要在借条上加上签名。这个步骤在比特币系统中则体现为数字签名。在比特币系统里,数字签名是一段字符串,但这段字符串只有信息的发送者才能产生,别人无法伪造。这段字符串同时也是对信息的发送者发送信息真实性的一个有效证明。所以有了借条和数字签名以后,支付信息的内容就可以被明确证明了。

现在支付信息可以确定了,但是还有另外一个问题。这就是我们又如何确定老王发了工资以后确实就能够还上这100块钱呢?

这个问题在中心化运作的系统里不成问题。但是则比特币不同,比特币是去中心化的。在比特币的系统里,账户里的钱有多少自己说了不算,因为没人会相信你。要解决这个问题的话,就要用另一种方法。那就是每笔交易都必须把以前的交易作为基础。当老王确定要还老赵的100块钱时,那么我们就要确定老王确实发工资了,工资额大于100元人民币,而且这笔钱没有用于其他支出。

于是在老王还钱的时候系统就会核实以下信息:

老王的公司给老赵发了1000元的工资,老王支付100元给老赵。然后再附上老王的数字签名和公钥。等老赵收到信息后,就会用SHA256算法进行确认,然后用私钥解锁。那么这笔交易也就可以确认了。

我们看上面这个过程,好像是从老王的工资中扣除了100元给老赵。但是在比特币系统中运行的实际情况并不是如此。

在比特币系统中,老王是没法把之前的1000块钱拆成一个100块和一个900块的。因为这个网络中每个支付信息都是由SHA256的签名标记过的,无法再进行拆分。所以这个支付过程其实是这样的。首先老王会一次过把1000块钱全部打给老赵。然后老赵会还给老王900块钱。

如果我们用现实世界的逻辑去看这个支付过程会觉得怪怪的。

你就不能一次给到位?怎么非要别人找钱?

但是在比特币系统里,我们只能这么支付。因为所有写入账本的信息必须以之前的交易为基础。这就导致了,我们无法将一笔钱拆成两个部分或者多个部分。

在比特币被发明的时候SHA256被公认为全球最安全最先进的算法之一。到目前为止,仍然没有公开的证据表明SHA256有漏洞,SHA256依旧牢牢抗住保卫比特币安全的大旗。但回顾人类历史,我们可以看到加密和解密总是相伴而生的。世界上没有永远安全的算法,SHA256被替代也是早晚的事,所以比特币要想持续稳定的运行那就必须与时俱进,不断升级完善。