无法将 AppId 扩展与 WebAuthn 用于先前注册的 U2F 密钥

Phi*_*ley 5 fido-u2f webauthn

随着u2f api 的显着消亡,我尝试使用 AppId 扩展转向 WebAuthn API,以支持之前在 U2F 注册的安全密钥。从阅读文档中我可以看出,我认为我做得正确,但是,当尝试进行身份验证时,浏览器提示我点击我的密钥,并且我的密钥正在闪烁,但是点击它后,我收到错误“您“正在使用未在此网站注册的安全密钥”。在比较现有的 u2f 身份验证请求时,我使用相同的 appid 和密钥句柄。

U2F 签名请求示例:

{
  "version": "U2F_V2",
  "challenge": "zSeDYPUjDVbLQ9HDle3g2QYrHEdG5vGBwAhzqdm_PAY",
  "appId": "https:\/\/subdomain.domain.net\/app-id.json",
  "keyHandle": "H-tBDjS1Fgr19cprKYUnZ9cDSE2AiX_Ld1kdPR2ruhIUbYr7jP3dflxkjZmfvqxkg5q84eXBr3ium3ETJ61Fww"
}
Run Code Online (Sandbox Code Playgroud)

这是我的服务器响应,它被传递给 webauthn js 库:

{
  "publicKey": {
    "challenge": "iygioh7vECe9OCQ5K0IBa0XeTD5hxX+aOBGimrJAntg=",
    "timeout": 60000,
    "rpId": "domain.net",
    "allowCredentials": [
      {
        "type": "public-key",
        "id": "SC10QkRqUzFGZ3IxOWNwcktZVW5aOWNEU0UyQWlYX0xkMWtkUFIycnVoSVViWXI3alAzZGZseGtqWm1mdnF4a2c1cTg0ZVhCcjNpdW0zRVRKNjFGd3c="
      }
    ],
    "userVerification": "discouraged",
    "extensions": {
      "appid": "https://subdomain.domain.net/app-id.json"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

该凭证 ID 的 Base64 url​​ 解码版本是

H-tBDjS1Fgr19cprKYUnZ9cDSE2AiX_Ld1kdPR2ruhIUbYr7jP3dflxkjZmfvqxkg5q84eXBr3ium3ETJ61Fww
Run Code Online (Sandbox Code Playgroud)

我注意到在我们的 U2F 版本中,appid url 由于某种原因被转义,因此我在 WebAuthn 版本中尝试了相同的操作,但这并没有什么区别。

我还尝试了不带尾随填充 ( ) 的挑战和凭证 ID =,但这也没有帮助。

我们用来与 webauthn API 交互的 JS 客户端似乎正在将质询和凭证 ID 解码到二进制数组缓冲区中。以下是作为 publicKey 发送到 navigator.credential.get API 的对象的控制台日志:

H-tBDjS1Fgr19cprKYUnZ9cDSE2AiX_Ld1kdPR2ruhIUbYr7jP3dflxkjZmfvqxkg5q84eXBr3ium3ETJ61Fww
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?我们有数千名用户使用 yubikeys 和 u2f,并且在如此短的迁移时间范围内,我们确实需要这种向后兼容选项才能发挥作用。

解决方案:@IAmKale 是对的,这是一个双重编码问题,或者可能是一个三重编码问题。无论如何,解决方案是H-tBD...在发送回浏览器之前需要对字符串进行原始 url base64 解码。感谢@IAmKale 提出的建议,帮助我们解决了这个问题!

IAm*_*ale 3

有关您传递给的选项的所有内容看起来navigator.credentials.get()都是正确的,包括您指定"appid"扩展名的方式。我认为问题在于您对U2F 凭证的凭证 ID 进行了双重编码。尝试在选项中传递原始文件"keyHandle"(您可以按原样使用它,因为它已经与 base64url 编码兼容):

{
  "publicKey": {
    "challenge": "iygioh7vECe9OCQ5K0IBa0XeTD5hxX+aOBGimrJAntg=",
    "timeout": 60000,
    "rpId": "domain.net",
    "allowCredentials": [
      {
        "type": "public-key",
        "id": "H-tBDjS1Fgr19cprKYUnZ9cDSE2AiX_Ld1kdPR2ruhIUbYr7jP3dflxkjZmfvqxkg5q84eXBr3ium3ETJ61Fww"
      }
    ],
    "userVerification": "discouraged",
    "extensions": {
      "appid": "https://subdomain.domain.net/app-id.json"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我几乎可以肯定,这就是让 WebAuthn 使用您的旧 U2F 凭据所需要做的全部事情。如果仍然不起作用,请设置为您发布的 U2F 签名请求中的"appid"转义URL,然后重试。"appId"