YubiKey + Webauth:userHandle 始终为空
YubiKey + Webauth: userHandle is always null
当我使用 WebAuthn 和我的 YubiKey 进行身份验证时,response.userHandle 属性 始终为空。那是我注册凭据的用户 ID 和显示名称不会返回。这是因为我在注册/身份验证过程中做错了什么吗:
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?
我试图了解您正在处理的问题。我玩 https://u2f.bin.coffee/ 来感受一下数据流。作为身份验证的结果,我收到了如下回复:
Got response:
{
"keyHandle": "F74UNCdNv1d43zw7hqxYgkjR3O6dcevopiSb3jrcB3rMFRUM486LbsVExJD0R3ESC5MCb3zeFGdxvS3ksZ7sCA",
"clientData": "eyJ0eXAiOiJuYXZpZ2F0b3IuaWQuZ2V0QXNzZXJ0aW9uIiwiY2hhbGxlbmdlIjoiTXpPTjhXRHpvSDlhZHU0bTk5YWF0ZyIsIm9yaWdpbiI6Imh0dHBzOi8vdTJmLmJpbi5jb2ZmZWUiLCJjcm9zc09yaWdpbiI6ZmFsc2UsImV4dHJhX2tleXNfbWF5X2JlX2FkZGVkX2hlcmUiOiJkbyBub3QgY29tcGFyZSBjbGllbnREYXRhSlNPTiBhZ2FpbnN0IGEgdGVtcGxhdGUuIFNlZSBodHRwczovL2dvby5nbC95YWJQZXgifQ",
"signatureData": "AQAAAAUwRAIgEqi5POKKUraU97W3vbfn34DSWqXwiZwEi5g9QPPtS6MCIBbLYW1_b3aRjHQivSRZQUAfBobx6CZnQ0_VVvuu1LJJ"
}
现在我假设 keyHandle
是你的 authenticatorData
,clientData
是你的 clientDataJSON
,signatureData
是你的 signature
.不管这个 userHandle
是什么,你都没有,它似乎不是必需的。
也看看this picture:
如果 userHandle
是 handle
,则身份验证将无法使用 null
值。但如果我正确理解你的例子,它就会起作用。
所以我相信您正在处理一个为将来目的或其他流程保留的字段,而不是您目前需要的字段。
userHandle
可以为空,具体取决于依赖方请求创建的 WebAuthn 凭证类型。
默认的 WebAuthn 行为将创建一个不可发现的凭据,并且断言中的 userHandle
returned 将为空。此类凭证的身份验证器上没有存储任何数据,因此 return.
没有任何数据
要创建 WebAuthn 客户端可发现凭证,a.k.a。常驻密钥,您必须将 requireResidentKey
成员设置为 true
。这会将凭证数据存储在身份验证器上,并将 return 断言中的 userHandle
。详见AuthenticatorSelectionCriteria in the W3C WebAuthn spec
这是一个例子:
authenticatorSelection: {
authenticatorAttachment: "cross-platform",
requireResidentKey: true
},
见Yubico's WebAuthn Dev Guide to learn more about resident keys and the userHandle。
当我使用 WebAuthn 和我的 YubiKey 进行身份验证时,response.userHandle 属性 始终为空。那是我注册凭据的用户 ID 和显示名称不会返回。这是因为我在注册/身份验证过程中做错了什么吗:
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?
我试图了解您正在处理的问题。我玩 https://u2f.bin.coffee/ 来感受一下数据流。作为身份验证的结果,我收到了如下回复:
Got response:
{
"keyHandle": "F74UNCdNv1d43zw7hqxYgkjR3O6dcevopiSb3jrcB3rMFRUM486LbsVExJD0R3ESC5MCb3zeFGdxvS3ksZ7sCA",
"clientData": "eyJ0eXAiOiJuYXZpZ2F0b3IuaWQuZ2V0QXNzZXJ0aW9uIiwiY2hhbGxlbmdlIjoiTXpPTjhXRHpvSDlhZHU0bTk5YWF0ZyIsIm9yaWdpbiI6Imh0dHBzOi8vdTJmLmJpbi5jb2ZmZWUiLCJjcm9zc09yaWdpbiI6ZmFsc2UsImV4dHJhX2tleXNfbWF5X2JlX2FkZGVkX2hlcmUiOiJkbyBub3QgY29tcGFyZSBjbGllbnREYXRhSlNPTiBhZ2FpbnN0IGEgdGVtcGxhdGUuIFNlZSBodHRwczovL2dvby5nbC95YWJQZXgifQ",
"signatureData": "AQAAAAUwRAIgEqi5POKKUraU97W3vbfn34DSWqXwiZwEi5g9QPPtS6MCIBbLYW1_b3aRjHQivSRZQUAfBobx6CZnQ0_VVvuu1LJJ"
}
现在我假设 keyHandle
是你的 authenticatorData
,clientData
是你的 clientDataJSON
,signatureData
是你的 signature
.不管这个 userHandle
是什么,你都没有,它似乎不是必需的。
也看看this picture:
如果 userHandle
是 handle
,则身份验证将无法使用 null
值。但如果我正确理解你的例子,它就会起作用。
所以我相信您正在处理一个为将来目的或其他流程保留的字段,而不是您目前需要的字段。
userHandle
可以为空,具体取决于依赖方请求创建的 WebAuthn 凭证类型。
默认的 WebAuthn 行为将创建一个不可发现的凭据,并且断言中的 userHandle
returned 将为空。此类凭证的身份验证器上没有存储任何数据,因此 return.
要创建 WebAuthn 客户端可发现凭证,a.k.a。常驻密钥,您必须将 requireResidentKey
成员设置为 true
。这会将凭证数据存储在身份验证器上,并将 return 断言中的 userHandle
。详见AuthenticatorSelectionCriteria in the W3C WebAuthn spec
这是一个例子:
authenticatorSelection: {
authenticatorAttachment: "cross-platform",
requireResidentKey: true
},
见Yubico's WebAuthn Dev Guide to learn more about resident keys and the userHandle。