身份认证一直就是一个麻烦的问题。互联网时代,每个论坛注册一个用户名密码让人很烦恼,于是出现了OAuth,允许用户通过第三方网站(例如Google、Facebook、微博、QQ、微信)来认证自己,但仍然需要第三方公司的信任背书。 即将到来的区块链时代,能不能通过区块链相关的技术解决这个问题呢?当然方法有很多种,例如 blockstack 和其上的 onename ,就是尝试通过虚拟链来解决这个 问题的,而 崛起币 则通过区块链自身的键值对功能衍生出ssh登录和ssl身份验证。笔者认为,基于区块链的身份认证系统,在很长一段时间内,仍然是多种系统并存的,取决于市场竞争中哪个区块链会胜出。
我想设计一种基于现有区块链的互联网身份识别系统,初期包括比特股和Steem。网站和用户直接通过区块链自身作为公信第三方,互相知道对方的账号。在这个基础上可以做很多增值的应用,例如打赏和优惠券发放啥的。
静态部署图如下:
![graph 身份认证静态部署 {browser[shape="box"]site[shape="box"]blockchain[shape="insulator", label=""]user -- browserbrowser -- sitebrowser -- blockchainsite -- blockchain}](https://i-blog.csdnimg.cn/blog_migrate/462b72d64175a03a444b153ace4e42a5.png)
以bitshares为例,核心步骤是:
- 用户通过链外(https)报告自己的账号到服务器。
- 服务器通过自己的比特股账号向用户的账号发起一个特殊转账,包含加密的备注。
- 用户接收转账,确认了服务器的账号。
- 用户通过私钥解开转账的备注消息,并从链外通过服务器的公钥加密发给服务器。
- 服务器从链外收到用户发来的备注,用私钥解密,与自己之前发送的备注比较,确认了用户身份是否伪造。
- 互相就就确认对方了,再加cookie啥的避免重复认证。
- 其他增值应用功能都,通过私钥区块链广播,发起交易。
不妨把这个过程故事化了。假设张三想要访问一个李四做的论坛,但首先李四想要知道张三就是张三,张三也要知道李四就是李四,还好双方都在bitshares上注册了账号,分别就是张三和李四,于是借助于bitshares这个区块链和本文讨论的身份验证系统,一步一步达到了互相认证的目的。 张三首先访问了一个论坛网站,由于浏览器没有任何记录,上面出现一个按钮,写着“通过bitshares登录”,张三觉得这个按钮不错,于是点了一下。点过之后出现一个界面,要求张三用恢复bitshares钱包的方法来在这个域名下恢复钱包,于是张三恢复了自己bitshares钱包,并且把账号告诉 了网站服务器,网站服务器不知道张三真的是否注册或者就是张三,于是告诉访问者,我是李四,通过安全手段(bitshares)你转一笔小钱,里面还有一个暗号,你注意收下,并且把暗号再告诉我;服务器同时按照这个说法给张三转账。张三在区块链上监听来着李四的转账,果然收到了,并且看到了暗号,于是他 又把暗号通过链外告诉服务器。通过这个交互,张三知道服务器控制了李四这个身份,服务器知道使用服务的人就是张三,张三在浏览器上重定向到论坛的页面,并且有了浏览器本地的钱包。在最后一个交互(张三发确认暗号)中,服务器记录张三,并且发送cookie给张三使用的浏览器,用来确认后续链外行为是张三本人做的。
以上讨论正常流程,下面说下哪些分支流程会导致认证失败。
- 张三不相信在另一域名下解开bitshares钱包。这个无法在系统内解决,也许硬件钱包是一个好办法。
- 张三欺骗服务器,说自己叫张四,可是由于张三没有张四的私钥,就无法解开服务器发送转账的备注,因此服务器就知道认证失败了。
- 服务器欺骗张三,说自己叫李三,可是服务器无法以李三的名义发送转账,因此张三的浏览器就知道服务器撒谎了。
- 任何步骤超时,认证也会失败。
最后,考虑这个问题:如何防止DDoS攻击?由于服务器发送转账有成本,而一开始声称自己是谁的客户端没有成本,因此可以用这个方法欺骗服务器做无效的转账。这个应该通过多方面来防范:
- 链外做流量限制
- 链上,发行仅用于认证目的的没有什么价值的用户自定义资产
- 同一个用户切换浏览器后,可以复用之前的转账过程,而仅仅做链外的密文交换就可以知道对方的身份了
写到这里,我的脑子里突然又浮现了另一种想法,那就是无须在链上转账就能通过链下的声明和公私钥信息交换就可以认证对方了,岂不是更妙?不过还没有完全成形,等想好了下回再发一篇文章。