首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >非“常驻”密钥如何在WebAuthn中工作?

非“常驻”密钥如何在WebAuthn中工作?
EN

Cryptography用户
提问于 2023-04-03 14:30:27
回答 1查看 170关注 0票数 1

如果我们查看WebAuthn规范,那么在“注册”仪式期间,身份验证者将生成一个新的密钥对和一个唯一的用户id。然后将公钥和唯一的用户id发送给依赖方(服务器),以及一些认证语句。依赖方将在其数据库中存储公钥和用户id,并将它们与用户帐户相关联。

稍后,在“身份验证”仪式期间,依赖方将用户id发送回客户端,并附带随机挑战。身份验证者使用用户id来找到正确的私钥(在“注册”仪式上生成的私钥),这样它就可以用该密钥对挑战进行签名。最后,签名质疑被发送给依赖方,在依赖方将用相应的公钥(在“注册”仪式期间存储的公钥)对签名进行验证。

https://www.w3.org/TR/webauthn-2/images/webauthn-registration-flow-01.svg

https://www.w3.org/TR/webauthn-2/images/webauthn-authentication-flow-01.svg

这显然要求身份验证者将私钥存储在内部内存中。否则,它将无法根据给定的用户id查找私钥并使用它来签署挑战。至少,我看不到客户机/身份验证器从依赖方得到任何东西,除了用户id。因此,实际上,身份验证器必须存储它生成的所有私钥(及其相应的用户id),以便将来的登录成为可能。

现在让我困惑的是:一些来源声称,通常私钥实际上存储在依赖方(以加密的形式)上,而不是在身份验证器中。并且只有所谓的“常驻”密钥(可发现的凭据)在本地存储在身份验证器中。但是,如果是这样的话,那么“正常”(非常驻)键是如何真正工作的呢?在WebAuthn API中,客户机或身份验证者将向依赖方发送加密的私钥,作为注册的一部分,我什么也看不见。此外,在WebAuthn API中,我看不到依赖方将加密的私钥发送回客户机/autenticator,作为身份验证的一部分.

可发现的凭据/驻留密钥WebAuthn允许使用无密码登录体验的高可靠性多因素身份验证。启用此功能的一个功能是所谓的可发现凭据,也称为驻留密钥。可发现凭证意味着私钥和相关元数据存储在身份验证器上的持久内存中,而不是加密和存储在依赖方服务器上。

那么,“正常”(而不是常驻) WebAuthn私钥真正存储在哪里呢?如果它存储在依赖方服务器上,正如一些消息来源所声称的那样,身份验证者和依赖方之间的加密私钥在哪里/何时交换?哪个API函数/对象可以这样做?

EN

回答 1

Cryptography用户

回答已采纳

发布于 2023-04-03 19:34:42

以下是它如何工作的简化模型。当然,来自每个不同供应商的每个设备的工作方式可能不同,但这与旧式Yubico U2F实现的工作方式非常接近。

在设备上有一个32字节的主主机HMAC- the 256密钥k.

  • 当您使用将设备注册到网站 (navigator.credentials.create,做authenticatorMakeAssertion),使用网站提供的依赖方id时,设备:
    1. 随机一致地生成32字节令牌t .
    2. 导出种子s = \operatorname{HMAC-SHA256}_k(\mathtt{0x01} \mathbin\| t \mathbin\| \mathit{rpId})
    3. 在NISTP-256上导出ECDSA的密钥对(\mathit{sk}, \mathit{pk}),确定地从seed s-e.g.将s解释为256位整数,对高比特进行零运算以选择低于组顺序的标量\mathit{sk},然后将标准基点乘以\mathit{sk}导出\mathit{pk}
    4. 计算32字节身份验证标记a = \operatorname{HMAC-SHA256}_k(\mathtt{0x02} \mathbin\| t \mathbin\| \mathit{rpId}).
    5. 返回t \mathbin\| a作为64字节凭据id,\mathit{pk}作为公钥。

  • 当您使用使用设备对网站进行身份验证。 (navigator.credentials.get,它执行authenticatorGetAssertion),使用依赖方id、凭据id和网站提供的挑战时,设备:
    1. 如果凭据id不是64字节长,则拒绝。
    2. 将64字节凭据id划分为32字节的t \mathbin\| a.
    3. 如果a \ne \operatorname{HMAC-SHA256}_k(\mathtt{0x02} \mathbin\| t \mathbin\| \mathit{rpId})拒绝。
    4. 导出种子s = \operatorname{HMAC-SHA256}_k(\mathtt{0x01} \mathbin\| t \mathbin\| \mathit{rpId})
    5. 在NISTP-256上导出用于ECDSA的密钥对(\mathit{sk}, \mathit{pk}),确定地从种子s中导出.
    6. 用私钥\mathit{sk}签名挑战并返回签名。

签名密钥\mathit{sk}仅通过将存储在设备上的主密钥k**与存储在服务器上的凭据id中的令牌** t相结合才能存在。一旦注册完成,它就不需要显式地存储在设备上;它只是在每个身份验证操作中重新派生出来。

诀窍是,从32字节种子中确定地为NIST P-256上的ECDSA生成密钥对是非常便宜的--曲线上的一个固定基标量乘法。通过运行完全相同的openssl speed ecdhp256-not操作(ECDH是可变基的,而不是固定基的),您可以粗略估计这会占用您的CPU多长时间,但这是一个合理的近似。

票数 1
EN
页面原文内容由Cryptography提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://crypto.stackexchange.com/questions/105942

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档