Karp 的技术博客

在数字时代,密码已成为我们日常生活和在线活动中不可或缺的一部分。尽管互联网已经发展了 20 多年,许多方面都有了巨大的改进,但只有密码,还是 20 年前的用法。

更准确的说,它的用户体验比 20 年前更差了。密码的强度现在要求越来越高,一般不能少于 8 个字符,还要包括特殊符号。另外,除了密码,通常还有其他验证(短信、图片识别、OTP 一次性密码等等)。

然而,即使变得如此麻烦,依然不能杜绝密码被盗、被破解、被钓鱼的风险。为了解决这些问题,WebAuthn 应运而生。

01 WebAuthn简介

WebAuthn,全称 Web Authentication,是由 FIDO 联盟(Fast IDentity Online Alliance)和 W3C(World Wide Web Consortium)联合制定的一套新的身份认证标准,旨在为网络身份验证提供一种更强大、更安全的方式,使用户能够使用他们的设备(如手机、USB 密钥或生物识别器)来进行身份验证,而无需使用密码。该标准于 2019 年 3 月 4 日正式成为 W3C 的推荐标准。目前主流的浏览器已经支持 WebAuthn,包括 Chrome、Firefox、Edge 和 Safari,更详细的支持情况可以通过 https://webauthn.me/browser-support 查看。

注:FIDO 联盟是一个非营利性组织,由 Google、微软、苹果、三星、高通、芯片厂商、支付公司、银行、电信运营商、认证公司等组成,旨在为用户提供更安全、更简单的身份验证体验。

02 WebAuthn的工作原理

WebAuthn 的原理并不复杂,它的核心是基于公钥的加密技术。在 WebAuthn 中,用户的身份认证是通过公钥和私钥来实现的。这很像我们平常使用配置了公私钥的 SSH 登录服务器的过程,只不过 WebAuthn 是在浏览器中实现的。

03 WebAuthn的组成部分

WebAuthn 由以下三个组成部分组成:

  1. 用户代理(User Agent):用户代理是指浏览器或者其他支持 WebAuthn 的客户端,它负责与用户进行交互,收集用户的身份认证信息,并将其发送给服务器。
  2. 身份验证器(Authenticator):身份验证器是指用于生成公钥和私钥的设备,如手机、USB 密钥或生物识别器。Windows Hello 和 macOS 的 Touch ID 也都是常见的身份验证器。
  3. Relying Party:Relying Party 是指需要进行身份认证的网站或应用程序,它负责生成挑战(Challenge)并将其发送给用户代理,然后验证用户代理发送的签名结果。
    上述三者在两个不同的用例(注册和认证)中协同工作,如下图所示。图中的各个实体之间的所有通信都由用户代理(通常是Web浏览器)处理。
    Xnip2024-02-24_12-04-29.png

04 WebAuthn的注册流程

Xnip2024-02-24_12-05-02.png
在注册时,用户端会生成一对公钥和私钥。其中,私钥存储在本地,而公钥则发送给服务器,服务端会将公钥与用户账户进行关联。详细的流程如下图所示:

Xnip2024-02-24_12-05-40.png

05 WebAuthn的认证流程

Xnip2024-02-24_12-05-55.png
在认证时,用户端会使用私钥对服务器端发送的挑战(Challenge)进行签名,然后将签名结果发送给服务器。服务器端会使用公钥对签名结果进行验证,从而完成身份认证。详细的流程如下图所示:

Xnip2024-02-24_14-07-32.png

你可以在 https://webauthn.me/ 上体验 WebAuthn 的注册和认证过程。

06 WebAuthn API

在上面的介绍中,涉及到两个主要的 API:

navigator.credentials.create()

navigator.credentials.get()

其中, navigator.credentials.create() 用于在注册阶段生成公钥和私钥。

navigator.credentials.get() 用于在认证阶段对服务端的挑战(Challenge)进行签名。

下面,我们将分别介绍这两个 API 的使用方法。

navigator.credentials.create()

const res = await navigator.credentials.create({
    publicKey: {
      // 随机的、加密安全的、至少 16 个字节的数据
      challenge: base64url.decode("<%= challenge %>"),
      // relying party 的信息
      rp: {
        name: "Awesome Corp", // Relying party 的名称
      },
      user: {
        id: base64url.decode("<%= id %>"),
        name: "<%= name %>",
        displayName: "<%= displayName %>",
      },
      authenticatorSelection: { userVerification: "preferred" },
      attestation: "direct",
      pubKeyCredParams: [
        {
          type: "public-key",
          alg: -7, // "ES256" IANA COSE Algorithms registry
        },
      ],
    },
  });

// 由于 res 并不是一个 JSON object,需要将 res 转换为 JSON object
const json = publicKeyCredentialToJSON(res);
// 将 json 发送给服务器
await post("/webauthn/register", {
    state: "<%= state %>",
    provider: "<%= provider %>",
    res: JSON.stringify(json),
});

navigator.credentials.get()

const res = await navigator.credentials.get({
    publicKey: {
      // 随机的、加密安全的、至少 16 个字节的数据
      challenge: base64url.decode("<%= challenge %>"),
      allowCredentials: [
        {
          id: base64url.decode("<%= id %>"),
          type: "public-key",
        },
      ],
      timeout: 15000, // 超过 15 秒未完成认证,则认为认证失败
      authenticatorSelection: { userVerification: "preferred" },
    },
  });

// 由于 res 并不是一个 JSON object,需要将 res 转换为 JSON object
const json = publicKeyCredentialToJSON(res);
// 将 json 发送给服务器
post("/webauthn/authenticate", {
    state: "<%= state %>",
    provider: "<%= provider %>",
    res: JSON.stringify(json),
});

07 WebAuthn的现状

说了这么多,WebAuthn 现在的应用情况如何呢?

目前,越来越多的服务已经开始正式支持 WebAuthn。就在今年 5 月,谷歌和微软同时宣布全面接入 WebAuthn,支持无密码登录。GitHub 也在几天前宣布开始公测无密码登录功能。

在去年的黑客马拉松中,我们就尝试使用 WebAuthn 实现了 MicroStrategy Library 的身份认证。点击播放下列视频,可查看实际效果:

原文地址 : https://zhuanlan.zhihu.com/p/644471521

WebAuthn 最大的优势就是它的安全性和便捷性,相信在不久的将来,它将会成为互联网身份认证的主流方式。

参考资料:

https://www.ruanyifeng.com/blog/2023/07/weekly-issue-262.html

https://webauthn.guide/#intro

https://webauthn.me/introduction

https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API

https://blog.techbridge.cc/2019/08/17/webauthn-intro

WebAuthn

版权属于:karp
作品采用:本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
更新于: 2024年02月24日 06:13
7

目录

来自 《WebAuthn: 真正的无密码身份认证》