PublicKeyCredentials Webauthn "internal" 身份验证缺少 Android 上的用户句柄(Android Saftynet)

PublicKeyCredentials Webauthn "internal" authentication missing userHandle on Android (Android Saftynet)

我目前可以使用以下方法创建 publicKeyCredentials:

navigator.credentials.create({
      challenge: Uint8Array.from('CCCCCCCCCCCCCCCCCCCCCC', c => c.charCodeAt(0)),
      rp: {
        id,
        name: 'rpName'
      },
      user: {
        id: Uint8Array.from('userHandleId', c => c.charCodeAt(0)),
        name: 'userName',
        displayName: 'DisplayName'
      },
      pubKeyCredParams: [{alg: -7, type: 'public-key'}],
      authenticatorSelection: {
        userVerification: 'discouraged',
        authenticatorAttachment: 'platform',
        requireResidentKey: true, // don't seem to do anything with android-saftynet
        residentKey: 'required' // don't seem to do anything with android-saftynet
      },
      timeout: 60000,
      attestation: 'direct'
    })

然后使用以下方法检索凭据:

navigator.credentials.get({
        publicKey: {
          challenge: generateChallenge(),
          allowCredentials: [{
            id: decodeArray(id),
            type: 'public-key'
          }],
          timeout: 60000,
          transport: ['internal'],
          userVerification: 'discouraged'
        },
      })

此流程适用于我所有的苹果设备,但是,在 Android 上,凭据的 'fmt' 是 'android-saftynet',它似乎不支持 userHandles。

有没有我可以强制 Android 保存 userHandles 的格式?或者另一种使用 publicKeyCredential 存储信息以允许我支持无用户名 webauthn 流程的方法?

编辑:看起来 android-saftynet 不支持 userHandle。有谁知道是否有支持 userHandle 的 Android 验证器流程? (除了 USB 授权流程)

This flow works on all of my apple devices, however, on Android the 'fmt' of the credentials is 'android-saftynet' which doesn't seem to support userHandles.

澄清一下,证明声明 的格式与验证器从 navigator.credentials.get() return userHandle 的能力无关.根据规范 it's basically up to the authenticator whether it wants to return userHandle or not.

Are there any formats I can force on Android that I can save userHandles with?

WebAuthn 不提供任何方式让 RP(依赖方,即您的服务器)要求特定的证明站格式,因此您要么必须全部支持它们(对此我强烈建议您 use an existing library) 或选择并拒绝使用您不想支持的语句注册凭据。

Or another way to store information with the publicKeyCredential to allow me to support the usernameless webauthn flow?

如果我错了,我会更正,但我认为您不需要 userHandle 来完成无用户名。您应该能够获取从 navigator.credentials.get() 返回的凭据 ID,并首先将其与您的注册凭据列表进行匹配,然后从您自己的内部记录中提取相应的用户 ID,其中哪些凭据属于哪个用户。

综上所述,Android 对 FIDO2 的支持有点参差不齐。最后我检查了平台上基本上不支持可发现的凭据,这意味着 Android 设备上的无用户名支持目前几乎不可能。

证明(具有各种格式,例如 android-safetynet)和无用户名流是两个完全不同的概念。您可以拥有无​​需证明的无用户名流(格式 none)。

Attestation 允许您验证身份验证器本身 - 身份验证器是否实际上是 iPhone、Yubikey 或(非根)Android 设备,以及诸如密钥 material 之类的属性存储或指纹扫描仪的误报率是多少。有关详细信息,请参阅 https://fidoalliance.org/fido-technotes-the-truth-about-attestation/ and https://medium.com/webauthnworks/webauthn-fido2-demystifying-attestation-and-mds-efc3b3cb3651

在 WebAuthn 级别 1 中,无用户名注册(使用 requireResidentKey: true)被允许继续,即使用户代理不支持这一点(参见 authenticatorMakeCredential operation step 20)。在级别 2 中,一些事情发生了变化:

  • 常驻密钥现在称为客户端可发现凭证,
  • requireResidentKey 布尔值已更改为 residentKey 枚举,但仍然支持向后兼容,
  • authenticatorMakeCredential 操作已更改为 return 如果不支持客户端可发现凭据,step 4 中的错误,
  • credProps extension was added to determine if a client-side discoverable credential was created, either at the request of the RP or because the authenticator chose to (step 7.4).

使用 Chrome 97 的 Android 在撰写本文时不支持无用户名身份验证(具有空 allowCredentials 数组)。这已成为 known issue一会儿。