我在ConsenSys为各种客户构建了大量的概念证明,通常他们想要利用以太坊区块链来解决某些业务用例。奇怪的是,这些系统通常设计有标准的网络登录(即用户名和密码)。我总是问自己为什么我还在这样做设计,毕竟,这是今天以太网目前可以解决每个烦人的Web应用程序的一个方面。所以我决定停下脚步,设计一下这个解决方案。
JSON Web token
登录标准Web系统(和/或使用其API)的一种非常流行的方法是将密码(经过哈希的客户端)提交给认证端点并接收token作为回报。这通常称为JSON Web Token,通常在一段有限的时间内(几分钟到几天)有效。这是一个关于标准实现的很好的教程。
JSON Web Token很好,我开始认为在区块链上验证自己很容易。事实上,当你使用以太坊时,你需要不断地去改进。
如果你将以太网地址(这只是公钥的sha3哈希)视为网站上的帐户,则可以通过使用私钥对一段数据进行签名来证明你拥有该帐户,这非常容易。此数据是任意的,可以是网站API提供的任意随机字符串。因此,我们可以使用地址作为用户名并绕过密码的需要。事实上,我们甚至不需要使用区块链来做到这一点。
这是使用Express的样子:
首先,我们需要使用私钥进行椭圆曲线签名:
var ethUtil = require(‘ethereumjs-util’); // >=5.1.1
var data = ‘i am a string’;
// Elliptic curve signature must be done on the Keccak256 Sha3 hash of a piece of data.
var message = ethUtil.toBuffer(data);
var msgHash = ethUtil.hashPersonalMessage(message);
var sig = ethUtil.ecsign(msgHash, privateKey);
var serialized = ethUtil.bufferToHex(this.concatSig(sig.v, sig.r, sig.s))
return serialized
不要过分担心这些参数是什么。这里有一些密码学,我鼓励你阅读椭圆曲线签名。比特币维基是一个不错的起点。
无论如何,一旦我们有了签名组件,我们就可以将它们与用户的地址一起打包并将其全部发送到认证端点。
POST/Authenticate
var jwt = require(‘jsonwebtoken’);
var ethUtil = require('ethereumjs-util');
function checkSig(req, res) {
var sig = req.sig;
var owner = req.owner;
// Same data as before
var data = ‘i am a string’;
var message = ethUtil.toBuffer(data)
var msgHash