无法将 AppId 扩展与 WebAuthn 一起用于以前注册的 U2F 密钥
Unable to use AppId extension with WebAuthn for previously registered U2F keys
对于杰出的 demise of the u2f api, I'm trying to move to WebAuthn APIs using the AppId extension to support security keys previously registered with U2F. As best I can tell from reading the docs 我认为我做的是正确的,但是,当我尝试进行身份验证时,我的浏览器提示我点击我的密钥,并且我的密钥在闪烁,但是在点击它时我得到了错误“您正在使用未在该网站注册的安全密钥”。在比较现有的 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 解码为二进制数组缓冲区。这是作为公钥发送到 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"
}
}
我做错了什么?我们有成千上万的用户将 yubikeys 与 u2f 一起使用,并且迁移时间如此短,我们确实需要这个向后兼容选项才能工作。
解决方法:
@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 再试一次。
对于杰出的 demise of the u2f api, I'm trying to move to WebAuthn APIs using the AppId extension to support security keys previously registered with U2F. As best I can tell from reading the docs 我认为我做的是正确的,但是,当我尝试进行身份验证时,我的浏览器提示我点击我的密钥,并且我的密钥在闪烁,但是在点击它时我得到了错误“您正在使用未在该网站注册的安全密钥”。在比较现有的 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 解码为二进制数组缓冲区。这是作为公钥发送到 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"
}
}
我做错了什么?我们有成千上万的用户将 yubikeys 与 u2f 一起使用,并且迁移时间如此短,我们确实需要这个向后兼容选项才能工作。
解决方法:
@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 再试一次。