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



随着u2f api的显著消亡,我正试图使用AppId扩展来支持以前在u2f注册的安全密钥,从而转移到WebAuthn api。从阅读文档中我可以看出,我认为我做得很正确,然而,当试图进行身份验证时,浏览器会提示我点击我的钥匙,我的钥匙在闪烁,但点击后我会收到错误";您使用的安全密钥未在此网站注册;。在比较现有的u2f身份验证请求时,我使用了相同的appid和密钥句柄。

U2F签名请求示例:

{
"version": "U2F_V2",
"challenge": "zSeDYPUjDVbLQ9HDle3g2QYrHEdG5vGBwAhzqdm_PAY",
"appId": "https://subdomain.domain.net/app-id.json",
"keyHandle": "H-tBDjS1Fgr19cprKYUnZ9cDSE2AiX_Ld1kdPR2ruhIUbYr7jP3dflxkjZmfvqxkg5q84eXBr3ium3ETJ61Fww"
}

这是我的服务器响应,它被交给了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"
}
}
}

该凭证id的base64 url解码版本是

H-tBDjS1Fgr19cprKYUnZ9cDSE2AiX_Ld1kdPR2ruhIUbYr7jP3dflxkjZmfvqxkg5q84eXBr3ium3ETJ61Fww

我注意到在我们的U2F版本中,由于某种原因,appid url被转义了,所以我在WebAuthn版本中尝试了同样的方法,但这并没有什么不同。

我也尝试过不使用尾随填充(=(的质询和凭据id,但这也没有帮助。

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

{
"challenge": { "0": 83, "1": 195, "2": 81, "3": 9, "4": 32, "5": 53, "6": 59, "7": 244, "8": 34, "9": 113, "10": 189, "11": 177, "12": 61, "13": 184, "14": 170, "15": 86, "16": 43, "17": 206, "18": 102, "19": 145, "20": 218, "21": 136, "22": 137, "23": 18, "24": 14, "25": 176, "26": 210, "27": 54, "28": 201, "29": 57, "30": 156, "31": 21},
"timeout": 60000,
"rpId": "domain.net",
"allowCredentials": [
{
"type": "public-key",
"id": { "0": 72, "1": 45, "2": 116, "3": 66, "4": 68, "5": 106, "6": 83, "7": 49, "8": 70, "9": 103, "10": 114, "11": 49, "12": 57, "13": 99, "14": 112, "15": 114, "16": 75, "17": 89, "18": 85, "19": 110, "20": 90, "21": 57, "22": 99, "23": 68, "24": 83, "25": 69, "26": 50, "27": 65, "28": 105, "29": 88, "30": 95, "31": 76, "32": 100, "33": 49, "34": 107, "35": 100, "36": 80, "37": 82, "38": 50, "39": 114, "40": 117, "41": 104, "42": 73, "43": 85, "44": 98, "45": 89, "46": 114, "47": 55, "48": 106, "49": 80, "50": 51, "51": 100, "52": 102, "53": 108, "54": 120, "55": 107, "56": 106, "57": 90, "58": 109, "59": 102, "60": 118, "61": 113, "62": 120, "63": 107, "64": 103, "65": 53, "66": 113, "67": 56, "68": 52, "69": 101, "70": 88, "71": 66, "72": 114, "73": 51, "74": 105, "75": 117, "76": 109, "77": 51, "78": 69, "79": 84, "80": 74, "81": 54, "82": 49, "83": 70, "84": 119, "85": 119}
}
],
"userVerification": "discouraged",
"extensions": {
"appid": "https://subdomain.domain.net/app-id.json"
}
}

我做错了什么?我们有成千上万的用户使用带有u2f的yubikeys,在如此短的迁移时间内,我们真的需要这种向后兼容性选项来工作。

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

传递给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"
}
}
}

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

最新更新