用简洁方式讲解 Passkeys 无密码认证原理与优势,帮助开发者理解下一代身份验证的实现细节。
一个密码,是一个你必须记住、网站必须存储(理想情况下进行哈希处理)的秘密。问题在于,这个系统完全依赖于两个薄弱环节:
你,因为你厌倦了想出新密码,所以在各处重复使用同一个密码。
网站,它可能被黑客攻击,密码数据库泄露。
再加上钓鱼攻击:一个完美模仿真网站的虚假网站可以在你不知情的情况下窃取你的密码。这不是个小问题——Verizon 的 DBIR 报告每年都在提醒,社会工程学、钓鱼攻击和被盗凭证仍然是全球黑客的主要原因之一,与软件漏洞并列。
即使有密码管理器和双因素认证,基本漏洞仍然存在:一个你可能意外泄露的秘密。
一个 passkey 基于非对称密码学,这个原理和你生成密钥对连接到服务器时用的 SSH 相同。
当你为一个网站创建一个 passkey 时:
你的设备(手机、电脑、安全密钥)生成一对密钥:一个私钥和一个公钥。
私钥永远不会离开你的设备。它被存储在一个安全芯片中:iPhone/Mac 上的 Secure Enclave,Windows 上的 TPM,或者像 YubiKey 这样的 USB 密钥的芯片中。
公钥被发送到网站并存储在服务器上。
要登录时,网站向你发送一个挑战(一个随机数),你的设备用私钥对其签名,网站用公钥验证签名。如果匹配,你就被认证了。
没有秘密在网络上传输,只有一个签名。W3C 的 WebAuthn 规范中写得很清楚:没有什么可以被窃取,没有什么可以被钓鱼。
关键点:一个 passkey 与它被创建的域名绑定。如果你去 paypa1.com 而不是 paypal.com,你的设备甚至不会建议使用 passkey。这是浏览器/操作系统做的验证,而不是你。Google 解释得很好:与密码不同,passkey 在密码学上与为其创建的网站相关联,因此不可能被拦截或在虚假网站上重复使用。天生抵抗钓鱼攻击,而不是靠用户的善意。
从技术上讲,passkeys 依赖于 WebAuthn 标准(W3C),它是由 FIDO Alliance 支持的更广泛的 FIDO2 标准的一部分(Google、Apple、Microsoft、Yubico 都是成员)。这是浏览器在 JavaScript 中公开的用于创建和使用凭证的 API。
根据 W3C WebAuthn 规范的注册流程图
在客户端创建一个 passkey 看起来像这样:
const credential = await navigator.credentials.create({
publicKey: {
challenge: new Uint8Array(32), // fourni par le serveur
rp: { name: "Mon Super Site", id: "monsupersite.com" },
user: {
id: new Uint8Array(16),
name: "[email protected]",
displayName: "Thomas",
},
pubKeyCredParams: [{ alg: -7, type: "public-key" }], // ES256
authenticatorSelection: { userVerification: "required" },
},
});
使用现有 passkey 登录的代码:
const assertion = await navigator.credentials.get({
publicKey: {
challenge: new Uint8Array(32), // fourni par le serveur
userVerification: "required",
},
});
服务器生成挑战,浏览器处理所有生物识别/解锁部分,然后返回给你一个要验证的签名。在服务器端,像 @simplewebauthn/server 这样的库在 Node.js 中完成大部分验证工作。
这是让每个人都卡住的问题,如果这个话题引起了你的兴趣,我之前写过一整篇关于被盗手机后双因素认证的麻烦——同样的"单点故障"原理也适用于 passkeys。自 2022 年以来,Apple、Google 和 Microsoft 已经添加了 passkey 同步功能:
在 iOS/macOS 上,它们通过你的 iCloud 钥匙串同步。
在 Android/Chrome 上,通过你的 Google 账户,使用 Google 密码管理器进行端到端加密的所有内容。
在 Windows 上,通过 Windows Hello,尽管跨设备同步在那里比 Apple 或 Google 更受限制。
所以如果你丢失了手机但在新设备上恢复了对 iCloud 或 Google 账户的访问权限,你的 passkeys 会跟随回来。你也可以使用一个物理安全密钥(YubiKey)作为备份,它不会同步但在任何兼容设备上都能工作——这与经典双因素认证的建议完全相同:永远不要把所有鸡蛋放在一个篮子里。
越来越多的服务已经提供了:Google、Apple、GitHub、Microsoft、PayPal、Amazon、X……Google 甚至更进一步,在个人账户上将 passkeys 设置为默认。通常你会在账户的安全设置中找到它,标记为"密钥"或"Passkey"。
你进入服务的安全设置。
你点击"添加密钥"或"创建 passkey"。
你的浏览器/操作系统要求你用 Face ID、Touch ID、Windows Hello 或你的手机代码确认。
完成。下次登录时,不需要密码了。
如果你想在你的操作系统钥匙串之外的地方管理你的 passkeys(如果你在不同的平台上很有用),ProtonPass 也知道如何创建和存储它们,采用端到端加密,与你的密码存储在同一个地方。
Passkeys 不仅仅是"隐藏在指纹后面的密码",这是一个完整的模型改变:没有什么可记住的,没有什么可被窃取的。如果一个服务建议你创建一个,就去做吧,这严格来说比你目前的密码更安全更快。
ProtonPass 在这篇文章中的链接是一个附属链接,这意味着如果你决定通过这个链接注册,我可能会获得佣金,对你没有额外成本。这帮助我支付托管费用/域名费用。感谢你的支持!