跳转到主要内容

category

安全上下文:此功能仅在安全上下文(HTTPS)、某些或所有支持的浏览器中可用。

Web身份验证API(WebAuthn)是凭证管理API的扩展,可通过公钥加密实现强身份验证,实现无密码身份验证和无SMS文本的安全多因素身份验证(MFA)。

注意:密钥是web身份验证的一个重要用例;有关实现的详细信息,请参阅为无密码登录创建密钥【 Create a passkey for passwordless logins】和通过表单自动填充使用密钥登录【 Sign in with a passkey through form autofill】。另请参阅Google Identity>Passwordless login with passkeys。

WebAuthn的概念和用法


WebAuthn使用非对称(公钥)加密技术代替密码或短信文本来注册、验证和对网站进行多因素验证。这有一些好处:

  • 防止网络钓鱼:创建虚假登录网站的攻击者无法以用户身份登录,因为签名会随着网站的来源而更改。
  • 减少了数据泄露的影响:开发人员不需要对公钥进行散列,如果攻击者能够访问用于验证身份验证的公钥,则无法进行身份验证,因为它需要私钥。
  • 易受密码攻击:一些用户可能会重复使用密码,攻击者可能会获取其他网站的用户密码(例如通过数据泄露)。此外,文本密码比数字签名更容易使用暴力。

许多网站已经拥有允许用户注册新帐户或登录现有帐户的页面,WebAuthn可以替代或增强系统的身份验证部分。它扩展了凭证管理API【 Credential Management API,】,抽象了用户代理和身份验证程序之间的通信,并提供了以下新功能:

  • 当navigator.credentials.create()与publicKey选项一起使用时,用户代理会通过验证器创建新的凭据,用于注册新帐户或将新的非对称密钥对与现有帐户关联。
    • 注册新帐户时,这些凭据存储在服务器(也称为服务或依赖方)上,随后可用于用户登录。
    • 非对称密钥对存储在验证器中,然后该验证器可以用于例如在MFA期间向依赖方验证用户。验证器可以嵌入到用户代理、操作系统(如Windows Hello)中,也可以是物理令牌(如USB或蓝牙安全密钥)。
  • 当navigator.certificate.get()与publicKey选项一起使用时,用户代理使用一组现有的凭据向依赖方进行身份验证(作为主登录名,或在如上所述的MFA期间提供附加因素)。

在最基本的形式中,create()和get()都从服务器接收一个非常大的随机数,称为“challenge”,并将私钥签名的challenge返回给服务器。这向服务器证明,用户拥有身份验证所需的私钥,而不会在网络上泄露任何机密。

注意:“挑战”必须是一个大小至少为16字节的随机信息缓冲区。

创建密钥对并注册用户


为了说明凭据创建过程是如何工作的,让我们描述一下当用户想要向依赖方注册凭据时发生的典型流程:

  • 依赖方服务器使用适当的安全机制(例如Fetch或XMLHttpRequest)将用户和依赖方信息连同“质询”一起发送到处理注册过程的web应用程序。
    • 注意:依赖方服务器和网络应用程序之间共享信息的格式取决于应用程序。推荐的方法是将JSON类型的表示对象交换为凭据和凭据选项。在PublicKeyCredential中创建了方便的方法,用于将JSON表示转换为身份验证API所需的形式:parseCreationOptionsFromJSON()、parseRequestOptionsFromJSON()和PublicKeyCredential.toJSON()
  • web应用程序代表依赖方,通过navigator.credentials.create()调用,通过验证器启动新凭据的生成。此调用传递一个publicKey选项,指定设备功能,例如,设备是否提供自己的用户身份验证(例如,生物识别)。典型的create()调用可能如下所示:
JS

let credential = await navigator.credentials.create({
  publicKey: {
    challenge: new Uint8Array([117, 61, 252, 231, 191, 241, ...]),
    rp: { id: "acme.com", name: "ACME Corporation" },
    user: {
      id: new Uint8Array([79, 252, 83, 72, 214, 7, 89, 26]),
      name: "jamiedoe",
      displayName: "Jamie Doe"
    },
    pubKeyCredParams: [ {type: "public-key", alg: -7} ]
  }
});

 

create()调用的参数与经过签名的SHA-256哈希一起传递给验证器,以确保其不会被篡改。

  • 在验证器【authenticator】获得用户同意后,它生成一个密钥对,并将公钥和可选的签名证明返回给web应用程序。当create()调用返回的Promise以PublicKeyCredential对象实例的形式(PublicKeyCredential.response属性包含证明信息)实现时,会提供此选项。
  • web应用程序再次使用适当的机制将PublicKeyCredential转发到服务器。
  • 服务器存储公钥和用户标识,以记住凭据,以便将来进行身份验证。在此过程中,它会执行一系列检查,以确保注册完整且未被篡改。其中包括:
    • 验证质询是否与发送的质询相同。
    • 确保原产地是预期的原产地。
    • 验证签名