这节要聊的话题是一个我们每天都会遇到,但是通常不会仔细想清楚原理的事情,那就是身份,也就是“我是谁”,另外一个相关的问题是认证身份,也就是“证明某人是某人”。肉身世界中,我们的身份似乎不需要什么认证,认识我的人自然知道我身份,数字世界中,登录网站的时候,通常我们是会用用户名和密码登录的,所以如何认证身份似乎是有多种方式的。但是其实不管在肉身空间还是数字空间,身份认证底层的逻辑都是统一的。我们来仔细挖一下,用纯技术的思路,来解释一下如何解决“我是谁”和“证明某人是某人”的这两个很有哲学味道的问题。
什么是身份认证?
一个人是可以有多种身份的。我可以同时是公民,司机,视频网站的用户,丈夫,儿子等等。作为一个喜欢做简化和抽象的程序员,我认为可以把身份抽象为一个身份文档。有了这个身份文档模型,我发现理解各种情景下的身份认证都可以按照统一思路来进行。
一个身份文档,就是一个存储到可信媒介上的包含两个数据的文档,这两个数据分别是身份名称和身份密钥。所谓身份名称,就是“我是谁”中的“谁”,例如,身份证上的公民姓名,某个网站用户名等等。身份密钥是可以证明我是这个人的不可伪造的信息。举个例子,每个人的公民身份证上就保存了一个身份文档。身份名称是我的姓名以及身份证号,而身份密钥是我的照片,或者说是我的长相。因为我的长相,或者说生物信息是不容易伪造的数据,所以可以用来做身份密钥。
身份认证的过程,就是被认证的对象,通过展示身份密钥来证明自己身份的过程。例如,我通过展示长相,就可以证明,我就是身份证上的那个公民。同时,身份文档还有另外一个重要特征,那就是要绑定到一个“可信”的存储媒介上。”可信“指的可以被“实施认证行为的人”,或者可以简称“验证人”,信任。例如,警察叔叔要确认一下我的身份,这时候,我要出示证据证明我是我,或者说是示证人,而这里警察叔叔就是验证人,那么身份证卡片就是他认为可信的存储媒介。而如果验证人不信任这个存储媒介,那么认证是无法成功的。身份认证过程,就是示证人出示身份密钥,来让验证人确认示证人的确是身份名称对应的那个人的过程。
再举一个更生活化的例子,套用一下上面的身份文档模型。例如,我有一个身份是儿子,我爸每次见到我,就能确认我就是他儿子,也就是说完成了身份认证,那么这个认证过程是怎样的呢?这里,身份名称就是”儿子“,身份密钥是我的长相。实施认证的人是我老爸,存储媒介是他自己的脑子,对他而言,当然是可信的存储媒介了。认证过程,就是我在他面前露个脸,他看到后,发现我的长相跟他脑子中的儿子长相吻合,于是认证成功。
传统上,身份认证指的是确认肉身身份和某个社会角色的绑定关系。但是我们的抽象模型也适用于被认证身份的对象是除了人之外的其他个体的情况,例如一个网站,一个设备,或者一个机器人。
总之,用一个身份文档的抽象模型,就可以很好的解释各种情况下的身份认证的过程了。
Web2.0 的身份认证过程
身份文档模型,也完全可以解释当前我们登录一个普通网站,实现身份认证的过程。
一个普通 Web2.0 App 的身份认证过程是这样的。App 数据库中保存了用户的 id ,例如 happypeter ,另外,还会保存密码。登录 App 的过程,就是输入用户 id 和密码,认证自己身份的过程。具体过程是,用户提交用户 id 和密码到网站服务器,App 会根据用户 id 查找到用户的密码,如果这次提交的密码跟数据库中保存的密码一致,那么认证就成功了,登录成功。套一下咱们的身份文档模型。验证人是 App ,示证人是用户。可信的存储媒介是 App 数据库,自己的数据库,App 当然会信任。身份名称,是用户 id,身份密钥是密码。密码是很简单的数字,密码之所以比较难以伪造,不是因为复杂,而是因为别人不知道。这里插一句,实际中比较常见的情况是,数据库中保存的不是密码本身,而是密码的哈希。用户登录时,服务器会把用户提交的密码做哈希运算,得到的结果跟数据库中的哈希值如果相同就证明用户提交的密码和注册时候的填写的密码是一致的,认证成功。可见,身份密钥的形式是多样的。被认证的对象展示的信息可以不是身份密钥本身,而是一个与之匹配的东西。
这就是 Web2.0 架构的 App 上实现身份认证的过程了。懂技术的读者可以去套一下, OAuth ,Facebook Connect ,微信登录等等各种其他方案是否符合咱们这里的文档模型。
去中心化的自主身份的认证过程
Web3.0 下,每个用户的身份都是自主身份,都是不存储在 App 数据库中的,所以认证思路也从中心化变成了去中心化的思路。但是,我们的身份文档的模型还是成立的。而且,我之所以要提出身份文档这个概念,并且给出前面几百字的略显直白的铺垫,就是为了让大家更顺畅的理解去中心化的身份认证过程。
我们以 DID 作为自主身份的代表。DID 运行的基础是存储在区块链上的 DID 文档。区块链是一个不可篡改的存储媒介,全球人都可以相信一旦 DID 保存到区块链上,没有任何人能修改它。一个 DID 文档中包含很多信息,其中包含 DID 号,对应身份名称,还包含公钥,对应身份密钥。如果我需要验证你是不是 DID 的所有者,只需要要求你出示数字签名即可。补一点公钥密码学的知识:公钥和私钥是一起生成的,是天生的一对,公钥可以公开给任何人,但是只有持有私钥的人才是公钥的拥有者。但问题是,去中心化条件下,我们不能向给 App 提交密码一样,直接展示私钥给实施认证的人,好在只要某人能够出示数字签名,就可以证明他肯定是持有私钥的。
基于 DID 的身份认证有这么几个特点。首先,DID 文档中的身份密钥是公开的,这个跟中心化条件下使用密码做身份密钥是有明显区别的,因为密码是要严格保密的。同时,认证过程中,被认证的人要持有的也不是文档中保存的身份密钥,而是一个跟身份密钥匹配的东西,也就是跟公钥配对的私钥。这个好比古代皇帝可以把一个玉璧摔成两半,自己和远征的将军各持有一半,未来用来作为信物,进行对传令人的身份认证。DID 的这种基于密码学的认证思路并不是什么新创造,熟悉 SSL 证书的同学,可以试着套一套咱们的身份文档模型,会发现也是完全符合的,而且跟 DID 非常的相似,只不过可信存储媒介从区块链变成了中心化的 CA 的数据库。
认证和授权是密不可分的。不熟悉 DID 的同学可能奇怪,DID 号只是一个随机数,为何也是一种身份呢?这种疑问是正常的。因为大部分时候,身份和权力是绑定的,也可以说,身份就是由权力和义务来定义的。例如,我是一个网站用户,那我就享有在网站内的一些权力。所以网站用户名,看起来更像一个真实的身份,而 DID 默认是不像的,因为它只是一串数字,没有绑定任何权力。在 Web 开发过程中,认证 Authentication 和授权 Authoriztion 是紧密相关的两个概念。Web2.0 网站中,对用户的授权是通过数据库来记录的,例如如果用户是 vip ,那么这个用户对应的数据库记录上就会有体现。使用 DID 这种自主身份,也可以用去中心化的形式实现授权的,如何对自主身份授权跟本节主题无关,这里暂时不展开。
关于,自主身份的认证就聊到这里。
结论
最后总结一下,结合本节的各种讨论,我们发现,不管是数字空间和肉身空间,不管是中心化条件下还是去中心化条件下,身份都可以抽象成为一个存储在可信媒介上的身份文档,文档中包括身份名称和身份密钥。身份认证,就是发起认证的人核对被认证人的密钥的过程。理解这个抽象,可以帮助我们更好的理解很多技术方案,例如 DID 的设计思路。