ddd009

ddd009

twitter

一文搞懂Dfinity的身份认证


title: 一文搞懂 Dfinity 的身份认证#

date: 2021-08-16 14:02:50

作者:ddd009
本文从基本的密码学概念讲起,详细解释了消息签名认证的过程,最后讲解了 Dfinity 是如何通过 Internet Identity 服务帮助用户管理自己的身份(密钥)的。

基本概念#

request

可以看到除了 canister ID,函数名称等常规请求信息,请求内容还包括用户的公钥与消息签名,Caller's Principal 是用户的公钥进行哈希得到的,下文中会具体讲解这一过程。被调用方收到消息后会使用用户的公钥验证签名的正确性,并检查公钥与 Caller‘s Principal 是否对应。

而 canister 的开发者是不需要理会底层的密码学细节的,只需要编写代码,Dfinity 会自动完成身份验证。

principal

这张图片展示了如何通过公钥得到用户的 Principal

首先从 DER 格式的公钥开始,对其进行 SHA-224 哈希运算,得到一个 28 字节的字符串,之后添加一字节用于区分用户 principal 和其他 principal,例如 canister 的 principal。

这 29 个字节是用户 principal 的二进制表示,可以看到 Motoko 和 JS 中 principal 变量是一个 Uint8 的 Blob 数组,里面保存的就是这 29 个字节

截屏 2021-08-16 上午 10.48.06.png

之后就是把这 29 个字节转化为文本表示的过程,首先添加 CRC32 错误检查码,再进行 Base32 编码,把最终得到的字符串以五个字符为一组分组,中间以 “-” 分隔,就得到用户的 prinicpal 文本表示。

顺便提一下,有base32 的社区实现 by flyq, 已经合并到 vessel-package-set,可以通过 vessel 进行使用。

如果说用户的 Principal 是与单一密钥绑定的将会非常不方便。如果说你有多个设备,那你需要在这些设备中使用同一个密钥,这即不方便又不安全。

Dfinity 使用了委托密钥的机制,如图你可使用黄色的密钥对橙色的密钥签名生成一个委托,包含作用域与过期时间。而橙色的密钥又可以对其他密钥进行委托,所以说这一方式是非常灵活的。

delgation

看到这里大家应该对于密钥对,用户 Principal,委托密钥这些基本概念有了大概的认识,那么 Dfinity 是如何使用这些密码学技术来完成用户身份验证的呢?

委托签名认证#

委托密钥的一种应用与 Web Auth 有关,Web Auth 是 W3C 推出的最新标准,主要针对与 web 应用的双重认证。也就是除了传统的用户名密码外,用户还需要对服务器发出的质询使用额外的安全设备进行签名,密钥是储存在安全芯片中的,不会发生泄漏,即时你的系统感染了木马,它们也不能对安全芯片中的密钥怎么样。通过这种方式可以确保是用户登录了服务器。

上面说的是传统互联网的做法,在 Dfinity 上这一过程有些许不同。使用中心化服务器时,你可以与服务器建立有状态的长连接,因此只需要对服务器发送的质询进行一次签名,之后的通信可以使用建立的连接传输。而在 Dfinity 上,并不存在一个中心化的服务器,我们不能同服务间建立有状态的连接,服务也不能主动向用户发出质询,因此用户需要对发出的每一条请求进行签名,而使用 Web Auth 时是需要对每次签名进行确认的,我们当然不能每发一次请求就触摸一下 Yubikey 或者按一次指纹,我们先生成一个短期的会话密钥,再使用 Web Auth 对会话密钥进行委托签名,最后用委托密钥自动完成对消息的签名。这样就解决了对多个消息签名的问题。

Internet Identity#

尽管 Web Auth 非常适合安全的存储密钥,但是由于浏览器的安全限制,密钥是与特定 canister 绑定的。在 IC 上只要 canister 不同就视为不同源,这种状态分离对于安全性至关重要。而这也给用户带来了麻烦,例如你很难跨设备使用同一个服务。针对这一缺点官方推出了 Internet Identity,简称 II,类似于 Sign With Google 的 SSO 服务,方便用户管理密钥与身份

identity

如图,应用前端生成会话密钥并将公钥发送至 II 服务,如果用户同意,II 服务将对会话密钥进行委托签名,所有的认证过程都是在用户端完成的。

image.png

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。