hello,我是海海
这一期是关于
通用密钥------PassKey
的一篇译作。阅读时间25分钟欢迎转载,请注明原文和作者
有任何疑惑的地方,欢迎后台留言
声明:本文观点除了笔者明确添加的表示自己的部分,其他均为原作者观点,与本人无关。
图1-1
原文标题: Passkeys: What the Heck and Why
原文作者: Neal Fennimore
文章分类: 安全
认证
通用密钥
核心观点:
本文涉及到的相关术语:
- Relying Party / Server:进行身份验证的环境,也就是服务器
- Client:发起身份验证的环境,可以是浏览器或者操作系统
- Authenticator:验证器,被允许生成及存储PassKey的软件或硬件系统
- FIDO:Fast IDentity Online(线上快速身份验证),是一种技术规范,应用在指纹登录、双因子登录等场景。因为可提高安全性、保护隐私及简化用户体验,目前Windows设备、iPhone手机、华为手机等都支持这种验证方案。
- WebAuthn:PassKeys的底层协议,也称为 FIDO2 凭证或单设备 FIDO 凭证。
- Passkeys:WebAuthn的一种实现,具备云同步(cloud syncing)
- Public Key Cryptography:公钥加密。包含了一对公钥/私钥,依据不同的算法,要么使用进行签名/验证,要么是用来加密/解密。其中一种知名的算法是非对称加密算法。
- RSA:一种较古老但仍然有用的基于素数分解的公钥加密技术
- Elliptic Curve Cryptography (ECC):一种前沿的,研究基于椭圆曲线的密码学
- ES256:椭圆曲线公钥,使用 ECDSA 签名算法 (PDF) 和 SHA256 进行哈希处理
- RS256:与 ES256 类似,但它使用带有 RSASSA-PKCS1-v1.5 和 SHA256 的 RSA
- passwords:身份验证的密码,就是所谓的账户密码
本期大纲:
- 啥是PassKey?
- PassKey替换密码,具体是如何实现的?
- 关于密码学,你可能需要了解的(可以跳过阅读)
- 如何生成PassKey?
- PassKey和WebAuthn之间有何区别?
- 让我们简单概括一下
- 重点来了!
- PassKey的缺陷
- 展望PassKey的未来
啥是PassKey?
在我们开始介绍PassKey之前,我们先来看看WebAuthn协议(也被称为FIDO2)。
WebAuthn是PassKey的基石,WebAuthn可以通过公钥加密替换密码(passwords)。
公钥加密生成的公钥可供任何人使用,但是存储私钥的物理设备由于保护私钥的需要,不应当转移它,因为可能有泄露的风险。这样,就相当于私钥和生成它的物理设备进行了绑定。
这就是WebAuthn的问题之一:如果小明丢失了物理设备,就会失去使用私钥访问的权限。
那么如何解决这个问题呢?
PassKey来了。
PassKey通过给认证添加云同步的能力,来解决这个问题。换句话说,小明在笔记本上生成的私钥也可以在移动设备上使用。
截止撰写本文前(2023年4月12日),IOS、Android、macOS提供了对云同步凭证的完全支持。当然,即便有完全支持,也会受到所使用浏览器本身的限制。
你需要知道的:Google和Apple分别使用了Google密码管理器和Apple iCloud钥匙串服务进行同步的工具。
PassKey替换密码,具体是如何实现的?
在公钥加密中:
对发送方而言,使用私钥对原始数据的散列值/散列函数(HASH)生成签名(sign)。然后将原始数据和sign提交给接收方。
接收方使用私钥对数据重新计算一次sign,对比两个签名,便可以知道数据是否被篡改,同时验证数据来源。
任何人都可以生成公钥对,它不属于任何人,因为它可以被任何人生成。它的意义在于只有私钥签名的数据能被公钥验证。
这是PassKey替换密码实现的原理------------服务器存储公钥,我们通过签署随机质询来验证我们是否拥有另一半(例如私钥)来登录。
笔者备注:
这段话是啥意思?
什么叫签署随机质询?
为什么签署了就能验证我们拥有另一半?
这段话的意思是,每次向服务器发起登录请求时,服务器会向小明发送一个随机字符串,小明的客户端环境使用私钥进行签名(sign),服务器根据存储在其中的公钥进行解密,如果解密后等于发送的字符串,即可证明小明就是小明,而不是小王或者小李。
PS:这有点像零知识证明
一个额外的好处是,由于我们将用户的公钥存储在数据库中,因此不再担心密码泄露会影响数百万用户。
这减少了网络钓鱼、违规行为以及我们依赖密码的世界目前面临的一系列其他安全问题。
如果数据库被破坏,所有信息都存储在用户的公钥中,这对攻击者来说几乎毫无用处。
也不会再忘记电子邮件及其相关密码!
浏览器会记住您在哪个网站上使用的凭据 - 您所需要做的就是单击几下,然后就可以登录了。
您可以提供第二种验证方式来使用PassKey,例如生物识别或 PIN 码,但这些仍然比过去的密码快得多。
关于密码学,你可能需要了解的(可以跳过阅读)
公钥加密涉及私钥和公钥(称为密钥对),它们一起被生成却具有不同的用途。
例如,私钥旨在保密,而公钥旨在供您想要与之交换消息的任何人使用。
当加密和解密消息时,接收者的公钥用于加密消息,以便只有接收者的私钥才能解密消息。
用安全术语来说,这称为"提供机密性"。
然而,这并不能证明发件人就是他们所说的人,因为任何人都可以使用公钥向某人发送加密消息。
在某些情况下,我们需要验证消息确实来自其发送者。(验证来源)
在这些情况下,我们使用签名和签名验证来确保发件人的真实身份(验证防篡改)。
在公钥(也称为非对称)加密中,这通常是通过对消息的哈希(散列)进行签名来完成的,以便只有公钥才能正确验证它。
哈希值和发送者的私钥通过算法运行后会生成签名,然后任何人都可以使用发送者的公钥验证消息是否来自发送者。
如何生成PassKey?
Authenticator是任何提供加密PassKey生成功能的硬件或软件支持的设备。
想一想您从 Google Authenticator、1Password 或 LastPass 等获得的一次性密码。
凭证可以远程存储并跨设备同步,例如:PassKey。硬件身份验证器类似于 YubiKey,它可以在设备本身上生成和存储PassKey。
要访问身份验证器,浏览器需要访问硬件,为此,我们需要一个接口。
我们在这里使用的接口是客户端到身份验证器协议 (CTAP)。它允许通过不同的机制访问不同的身份验证器。
例如,我们可以利用 CTAP 通过 NFC、USB 和蓝牙访问身份验证器。
使用万能钥匙的更有趣的方法之一是通过蓝牙将手机连接到另一台可能不支持万能钥匙的设备。当设备通过蓝牙配对后,我可以使用手机作为中介登录计算机上的浏览器!
PassKey和WebAuthn之间有何区别?
PassKey 和 WebAuthn 在几个方面有所不同。
首先,PassKey被视为多设备凭证,并且可以跨设备同步。相比之下,WebAuthn 是单设备凭证------这是一种奇特的方式,表示您绑定到一台设备进行验证。
其次,为了向服务器进行身份验证,WebAuthn 需要提供用于登录的用户句柄,之后服务器会将 allowCredentials 列表返回给客户端,该列表告知可以使用哪些凭据来登录。PassKey跳过此步骤并使用服务器的域名来显示哪些PassKey已绑定到该站点。您可以选择与该服务器关联的PassKey,因为您的系统已经知道它。
其他方面,两者在加密上是相同的;它们的区别仅在于存储方式以及用于启动登录过程的信息。
让我们简单概括一下
生成 WebAuthn 或 PassKey 的过程非常相似:
笔者备注:第一次登录
从服务器获取质询,然后使用 navigator.credentials.create (Web API) 生成公钥对。然后,将质询和公钥发送回服务器进行存储。
收到公钥和质询后,服务器会验证质询以及创建质询的会话。如果检查通过,则公钥以及任何其他相关信息(例如用户标识符或证明数据)将存储在数据库中。
笔者备注:后续登录
用户还有一个步骤 - 从服务器检索另一个质询并使用 navigator.credentials.get (WEB API) 对质询进行签名。我们将签名的质询发送回服务器,服务器验证质询,如果签名通过,则让我们登录。
重点来了!
看图1-3即可,过程在前文中或多或少的介绍过。
图1-3
笔者备注:
设置WebAuthn注册过程中的一些关键参数
ts
// The `challenge` is random and has to come from the server
const publicKey: PublicKeyCredentialCreationOptions = {
challenge: safeEncode(challenge),
rp: {
id: window.location.host,
name: document.title,
},
user: {
id: new TextEncoder().encode(crypto.randomUUID()), // Why not make it random?
name: 'Your username',
displayName: 'Display name in browser',
},
pubKeyCredParams: [
{
type: 'public-key',
alg: -7, // ES256
},
{
type: 'public-key',
alg: -256, // RS256
},
],
authenticatorSelection: {
userVerification: 'preferred', // Do you want to use biometrics or a pin?
residentKey: 'required', // Create a resident key e.g. passkey
},
attestation: 'indirect', // indirect, direct, or none
timeout: 60_000,
};
笔者备注:
创建一个新的公钥凭证
ts
const pubKeyCredential: PublicKeyCredential = await navigator.credentials.create({
publicKey
});
const {
id // the key id a.k.a. kid
} = pubKeyCredential;
const pubKey = pubKeyCredential.response.getPublicKey();
const { clientDataJSON, attestationObject } = pubKeyCredential.response;
const { type, challenge, origin } = JSON.parse(new TextDecoder().decode(clientDataJSON));
// Send data off to the server for registration
PassKey的缺陷
一方面,万能钥匙在某种程度上仍处于早期支持阶段。
Windows 上仅允许使用单设备凭据,而对 Linux 系统的支持很少。
此外,谷歌和苹果的万能钥匙平台无法相互通信。
如果您想将 Android 手机上的凭据转移到 iPhone 上......那么,您现在运气不好。这并不是说没有互操作性!您可以使用手机作为身份验证器登录计算机。但是,如果将其内置到操作系统中并进行同步,而不将其锁定在供应商级别,那么会更加干净。
Passkeys.dev 提供了一个很好的表,有点像该协议的 Caniuse。
图1-4
展望PassKey的未来
密钥绝不只在网络上受支持。 Android 和 iOS 都将作为一等公民支持本机密钥。我们仍处于这一切的早期阶段,但预计会看到它被越来越多地提及。
毕竟,我们消除了对密码的需求,并通过这样做让世界变得更安全!
好了,今天的旅程到这里就结束了,谢谢你的陪伴!
感谢你的耐心阅读,如果觉得好的话,可以给我点个赞吗
创作不易,感谢你的支持!
本文使用 markdown.com.cn 排版