重新创造比特币4:数字签名

作者:何岩,由 recreating.org发行。

0.前言 #

前篇说到了对称加密,并且我们发现没必要将交易的消息全部加密,因为交易数据不怕见光。只需要加密一小部分即可,究竟应该加密哪部分呢?

1.签名 #

既然我们的根本目的并不是防止别人看到交易数据的明文,而只是要用密文证明“我是我”。那么我的要求就是尽量加密更少的文字,即,加密付款者的名字。

这是为什么呢?

启发往往来自于现实生活的例子:

赵四想买台拖拉机,但是钱不够,向刘能借了1万块钱,刘能要求赵四写个借条。

赵四当然不愿意写啊,赵四就说自己不会写字。

刘能当然不能放过他啊,刘能就帮赵四写了欠条:“赵四欠刘能壹万元整”。
但是这个欠条并不具有法律效果,因为赵四可以说是刘能自己瞎写的。那么为了让这个借条成为证据,赵四最少也要签上自己的名字。因为赵四的笔迹是全世界唯一的,所以赵四签上了自己的名字,就代表着这个名字的本人认可这张借条的内容。如果赵四签的不是自己的名字,这张借条也不成立,也就是说赵四的唯一的笔迹,只在写自己的名字的时候借条生效。(见下图)

图片 1.png

签名

赵四的写字方式就是私钥,因为全世界就赵四能用这种方式写字。

“赵四”这俩个标准汉字就是公钥。

赵四的私钥(写字方式)只有在加密自己的公钥(“赵四”)的时候有法律效应,加密别人的公钥(签别人的名字)就无效。

反之,法官看到赵四的签名(那个写得乱七八糟的签字,等价于加密后的密文),可以用公钥来解密签名,因为公钥是“赵四”。

所以法官可以调取法院保存的签名数据库,找到赵四过往的签名来对比。

也可以传唤赵四本人出庭,让他辨认(解密)一下这个签名(密文)是不是自己签署(加密)的。

现实中我们管借条上的名字叫做签名,签名就是证明“我是我”的最少文字。
根据上面得到的灵感,借鉴到Bitcoin交易系统中,Alice用私钥加密自己的名字“Alice”即可作为证明,加密后的密文就称为:数字签名。(见下图)

图片 1.png

利用数字签名来证明Alice是Alice

2.签名用户名的漏洞 #

中本聪一遍一遍的在脑子里模拟着系统的运行,忽然发现了一个漏洞。

这个漏洞就是由于服务器没有存储用户名和公钥的对映关系,所以就不知道Alice的公钥是什么。如果有人用自己的公钥签署了别人的名字,法律上就等同于李四在借条上签了谢大脚的名字,是无效的。但是现在的设计中服务端没有能力判断,因为服务器没有类似法院的签名数据库。

如果Carol想要窃取Alice的Bitcoin:

1.Carol创建一条虚假的交易数据:“Alice to Carol 40”。

2.Carol用自己的私钥加密Alice的用户名,得到一个伪造的签名:“806535be3e“。

3.然后将Carol的公钥+伪造的签名+伪造的交易数据,放入消息中,发送给Bitcoin服务端。

4.服务端收到消息,解析得到三部分:公钥、签名、交易数据。

5.服务端利用Carol的公钥来解密Carol伪造的签名,得到明文的用户名:“Alice”。

6.服务器只会验证签名明文“Alice”是否等于交易数据中的付款方“Alice”。

问题就出在这里,服务端没有办法验证消息中收到的公钥是否是Alice的,而本例子中的公钥是Carol的,服务器端因为没有存储公钥和用户的对映关系,所以无法判断。

7.服务器验证通过,交易写入账本,交易生效!Carol成功的冒充Alice给自己转了40个Bitcoin。(见下图)

图片 1.png

使用用户名作为签名的漏洞

3.公钥替代用户名 #

那么这个漏洞的关键点在哪里呢?

关键点就在于,虽然服务器可以解密出签名的明文用户名,但是服务端不知道用户名和消息中的公钥是不是属于同一个人,也就是说服务端不知道Alice的公钥是什么,当然也不知道Carol的公钥是什么?所以Carol可以用自己的私钥来签署用户名为“Alice的签名。服务端用Carol的公钥来解密这个签名自然可以解开。

所以选择用户名来签名是行不通的。

如何绕过这个漏洞呢?

中本聪和Gilfoyle开始思考起来。

如果我们让服务器来存储用户名和公钥的对应关系,就又走回账户模型的老路了。

那么根本的解决思路是什么呢?

中本聪忽然有了灵感:“根本的解决的办法就是舍弃用户名!干脆用公钥来代替用户名!”

同样的场景:如果Carol想伪造一条Alice转账给自己的交易数据,就由上一个例子中的“Alice to Carol 40”变成了“公钥A to 公钥C 40”,其中我们用公钥A代表Alice的公钥,公钥C代表Carol的公钥。

整个流程是这样的:

1.Carol创建一条虚假的交易数据:“公钥A to 公钥C 40”,意思就是Alice的公钥转账给Carol的公钥40个Bitcoin。

2.Carol用自己的私钥加密Alice的公钥A,得到一个伪造的签名:“f9293ued3“。

3.然后将公钥C+伪造的签名+伪造的交易数据,放入消息中,通过网络发送给Bitcoin服务端。

4.服务端收到消息,解析后得到三个部分:公钥、签名、交易数据。

5.服务端利用Carol的公钥来解密Carol伪造的签名,得到明文的用户名:“公钥A”(即,Alice的公钥)。

6.服务器开始验证逻辑:比较消息中的公钥C和签名中解密出来的公钥A是否相等,显然这俩个公钥不相等,所以可以认定这笔交易不合法。

7.服务端拒绝继续处理,交易无效。
这样就解决了上面的漏洞,只需要将签名由加密用户名,改为加密公钥。(见下图)

图片 1.png

公钥替代用户名

4.将签名加入到交易模型中 #

中本聪在脑子里又模拟运行了几遍系统,忽然又出现了一个灵感:“现在的消息由三个部分组成:公钥,签名,交易数据。这里可以优化一下,首先可以去掉消息中的公钥参数,因为它和交易数据中的付款方公钥重复了。另外消息中的签名参数也可以去掉,我们将签名放入到交易数据中,变更下交易的模型,增加一个签名字段,这样签名就作为交易数据的一部分,可以被写入账本中,永远可查。”

Gilfoyle说:“这样的改动十分合理!交易模型中增加签名字段是很必要的,因为每笔交易的签名应该和交易的业务数据一起存储,并且永不分开。就好比欠条中的描述文字和签名不可分开一样,如果分开就等于欠条被撕成了两半,不再具备法律效应。”(见下图)

图片 1.png

消息的改造

改造之后的完整交易是这个样子(见下图)

图片 1.png

改造交易模型之后的交易

“到此为止,用户名就没有任何用处了,因为公钥可以替代用户名,user.txt也就没有存在的意义了,终于可以彻底舍弃账户模型了!”中本聪终于把用户注册的问题给根本性的解决了。

Gilfoyle说:“我们可以将用户的公钥理解成收款的地址,而不仅仅看成是用户名,虽然本质上他们是一个意思”。

“这个认知很棒!就像我订报纸的时候,不必告诉送报纸的人我的真名叫什么,我只要告诉他我的邮寄地址就可以啦。将公钥理解成收款地址而非用户名,的确更符合日常的生活经验。”

“我准备开始编码了,升级到只有账本模型的新版本”,中本聪一边说着一边打开电脑,迅速的敲打起来。

Gilfoyle慢慢悠悠的说:“我可以帮忙吗?”。
中本聪说:“太好了!你来改数据部分,我来搞程序部分,我把服务器的密码告诉你”。
Gilfoyle按照刚才的讨论,进入服务器,开始修改数据模型。
首先要将user.txt删除。
然后将transaction.txt中的用户名统统改成用户的公钥。
最后将签名字段加入到交易模型中。(见下图)

图片 1.png

数据模型的改造

5.后记 #

故事中的Bitcoin系统虽然引入了数字签名,并最终舍弃了账户模型。

但是,当前的设计是存在设计漏洞的,因为每次用户的签名不变,所以存在被重复使用的漏洞。例如Alice付款给Carol了50个Bitcoin,那么Carol就有动机,将这笔交易数据截获,并重复多次的向服务端发起相同的请求,服务端就会误以为Alice自愿支付多次50Bitcoin给Carol,直到Alice的余额减少到小于50bitcion。

这个漏洞将在后面的故事中修复。

下一篇:重新创造比特币5:公钥和私钥

相关链接 #

重新创造比特币:前言

Part One : 交易
重新创造比特币1:从一个简单的web交易系统开始
重新创造比特币2:第一个版本上线啦
重新创造比特币3:舍弃账户模型
重新创造比特币4:数字签名
重新创造比特币5:公钥和私钥
重新创造比特币6:第二个版本上线啦
重新创造比特币7:UTXO
重新创造比特币8:基于UTXO的系统重构
重新创造比特币9:万物皆交易
重新创造比特币10:交易脚本

Part Two : 群系统
重新创造比特币11:群系统(上)
重新创造比特币12:群系统(下)
重新创造比特币13:P2P网络
重新创造比特币14:交易的同步
重新创造比特币15:账本的同步
重新创造比特币16:Block Chain
重新创造比特币17:网络的弹性
重新创造比特币18:工作量证明(上)
重新创造比特币19:工作量证明(下)
重新创造比特币20:分叉之重组与分裂

书面设计矢量图_36.png

英文版Amazon.com在售 : Recreating Bitcoin

BSV打赏:
1Djc4TdVBi8urzmSXKHwg8cpEAYKcRQxgY

©2019 - Recreating.org all rights reserved

 
8
Kudos
 
8
Kudos

Now read this

Recreating Bitcoin 14:Synchronizing Transactions

Epilogue # In the last chapter, Satoshi and Gilfoyle complete the simplest P2P network but have not achieved the synchronization of the ledger across network. The first step to solve the problem is to synchronize the transactions.... Continue →