如果我们查看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函数/对象可以这样做?
发布于 2023-04-03 19:34:42
以下是它如何工作的简化模型。当然,来自每个不同供应商的每个设备的工作方式可能不同,但这与旧式Yubico U2F实现的工作方式非常接近。
在设备上有一个32字节的主主机HMAC- the 256密钥k.
navigator.credentials.create,做authenticatorMakeAssertion),使用网站提供的依赖方id时,设备:navigator.credentials.get,它执行authenticatorGetAssertion),使用依赖方id、凭据id和网站提供的挑战时,设备:签名密钥\mathit{sk}仅通过将存储在设备上的主密钥k**与存储在服务器上的凭据id中的令牌** t相结合才能存在。一旦注册完成,它就不需要显式地存储在设备上;它只是在每个身份验证操作中重新派生出来。
诀窍是,从32字节种子中确定地为NIST P-256上的ECDSA生成密钥对是非常便宜的--曲线上的一个固定基标量乘法。通过运行完全相同的openssl speed ecdhp256-not操作(ECDH是可变基的,而不是固定基的),您可以粗略估计这会占用您的CPU多长时间,但这是一个合理的近似。
https://crypto.stackexchange.com/questions/105942
复制相似问题