1

当我使用 WebAuthn 和我的 YubiKey 进行身份验证时,response.userHandle 属性始终为空。那就是我注册凭据的用户 id 和 displayName 没有得到返回。这是因为我在注册/身份验证过程中做错了什么:

async function register() {
  const publicKeyCredentialCreationOptions = {
    challenge: Uint8Array.from("this-is-a-test", (c) => c.charCodeAt(0)),
    rp: {
      name: "Webauthn Test",
      id: "localhost",
    },
    user: {
      id: Uint8Array.from("a1b2c3d4e5f6", (c) => c.charCodeAt(0)),
      name: "just-a-test",
      displayName: "MrUser",
    },
    pubKeyCredParams: [{ alg: -7, type: "public-key" }],
    authenticatorSelection: {
      authenticatorAttachment: "cross-platform",
    },
    timeout: 60000,
    attestation: "direct",
  };

  const credential = await navigator.credentials.create({
    publicKey: publicKeyCredentialCreationOptions,
  });
}

这是我用来验证的代码:

async function authenticate() {
  const publicKeyCredentialRequestOptions = {
    challenge: Uint8Array.from("test", (c) => c.charCodeAt(0)),
    allowCredentials: [
      {
        id: credentialId,
        type: "public-key",
        transports: ["usb", "ble", "nfc"],
      },
    ],
    timeout: 60000,
  };

  const assertion = await navigator.credentials.get({
    publicKey: publicKeyCredentialRequestOptions,
  });

  console.log(assertion);
}

我最终得到的是:

{
  rawId: ArrayBuffer(64),
  id: "U-nitqhlORmmdltp7TLO3i18KNoWsSebFyrtc3OIRvcktvwlz-dJZCA1_1gxXrNHzqReU7xGAHdfVP75N2aJSw", 
  response: {
    authenticatorData: ArrayBuffer(37) {}
    clientDataJSON: ArrayBuffer(101) {}
    signature: ArrayBuffer(71) {}
    userHandle: null
  }
  type: "public-key"
}

As you can see: userHandle is null.  Can anyone tell me why?
4

2 回答 2

6

可以为 null ,userHandle具体取决于依赖方请求创建的 WebAuthn 凭证类型。

默认的 WebAuthn 行为将创建一个不可发现的凭证,并且userHandle在断言中返回的将为空。此类凭证的身份验证器上没有存储任何数据,因此没有可返回的内容。

要创建 WebAuthn 客户端可发现凭证,也就是常驻密钥,您必须将requireResidentKey成员设置为true. 这会将凭证数据存储在身份验证器上,并将userHandle在断言中返回。有关详细信息,请参阅W3C WebAuthn 规范中的 AuthenticatorSelectionCriteria。

这是一个例子:

authenticatorSelection: {
  authenticatorAttachment: "cross-platform",
  requireResidentKey: true
},

请参阅Yubico 的 WebAuthn 开发指南以了解有关常驻密钥userHandle的更多信息。

于 2020-07-07T17:00:31.830 回答
0

我试图理解你在处理什么。我玩了https://u2f.bin.coffee/来感受一下数据流。作为身份验证的结果,我收到了如下响应:

Got response:
{
  "keyHandle": "F74UNCdNv1d43zw7hqxYgkjR3O6dcevopiSb3jrcB3rMFRUM486LbsVExJD0R3ESC5MCb3zeFGdxvS3ksZ7sCA",
  "clientData": "eyJ0eXAiOiJuYXZpZ2F0b3IuaWQuZ2V0QXNzZXJ0aW9uIiwiY2hhbGxlbmdlIjoiTXpPTjhXRHpvSDlhZHU0bTk5YWF0ZyIsIm9yaWdpbiI6Imh0dHBzOi8vdTJmLmJpbi5jb2ZmZWUiLCJjcm9zc09yaWdpbiI6ZmFsc2UsImV4dHJhX2tleXNfbWF5X2JlX2FkZGVkX2hlcmUiOiJkbyBub3QgY29tcGFyZSBjbGllbnREYXRhSlNPTiBhZ2FpbnN0IGEgdGVtcGxhdGUuIFNlZSBodHRwczovL2dvby5nbC95YWJQZXgifQ",
  "signatureData": "AQAAAAUwRAIgEqi5POKKUraU97W3vbfn34DSWqXwiZwEi5g9QPPtS6MCIBbLYW1_b3aRjHQivSRZQUAfBobx6CZnQ0_VVvuu1LJJ"
}

现在我假设keyHandle这里是你的authenticatorDataclientData这里是你的clientDataJSON,那signatureData是你的signature。无论userHandle您缺少什么,它似乎都不是必需的。

也看这张图

取自页面 https://developers.yubico.com/U2F/Protocol_details/Overview.html

如果userHandlehandle,则身份验证将无法使用null值。但是,如果我正确理解了您的示例,则可以。

因此,我相信您正在处理一个为未来目的或其他流程保留的字段,而不是您目前需要的字段。

于 2020-07-06T18:55:59.607 回答