在数字时代,密码已成为我们日常生活和在线活动中不可或缺的一部分。尽管互联网已经发展了 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 由以下三个组成部分组成:
- 用户代理(User Agent):用户代理是指浏览器或者其他支持 WebAuthn 的客户端,它负责与用户进行交互,收集用户的身份认证信息,并将其发送给服务器。
- 身份验证器(Authenticator):身份验证器是指用于生成公钥和私钥的设备,如手机、USB 密钥或生物识别器。Windows Hello 和 macOS 的 Touch ID 也都是常见的身份验证器。
- Relying Party:Relying Party 是指需要进行身份认证的网站或应用程序,它负责生成挑战(Challenge)并将其发送给用户代理,然后验证用户代理发送的签名结果。
上述三者在两个不同的用例(注册和认证)中协同工作,如下图所示。图中的各个实体之间的所有通信都由用户代理(通常是Web浏览器)处理。
04 WebAuthn的注册流程
在注册时,用户端会生成一对公钥和私钥。其中,私钥存储在本地,而公钥则发送给服务器,服务端会将公钥与用户账户进行关联。详细的流程如下图所示:
05 WebAuthn的认证流程
在认证时,用户端会使用私钥对服务器端发送的挑战(Challenge)进行签名,然后将签名结果发送给服务器。服务器端会使用公钥对签名结果进行验证,从而完成身份认证。详细的流程如下图所示:
你可以在 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.me/introduction
https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API