我在浏览器WebAuthn API中使用YubiKey和JavaScript。我正在尝试一个非常小的";你好,世界"只尝试做最小值的示例:navigator.credentials.create
,然后是navigator.credentials.get
(只演示最小值,甚至是硬编码值。
create
工作正常,但get
总是导致错误:
这个安全密钥看起来并不熟悉。
我很难理解理论上可能导致这种情况的原因。例如,据我所知,YubiKey实际上并没有在上面存储凭据,而是要求服务器发回一个包含密钥的加密不透明捆绑包。
但是get
API仅需要加密challenge
。(我认为这只是来自服务器的随机数据,而不是加密密钥?((目前,我基本上是在为挑战发送全零(。
示例显示allowCredentails
(这是一个可选字段(发送一个(或多个(ID。如果ID本身就是加密密钥,那么它应该使用这些密钥,这是有道理的。(但它们又是可选的(,即使我指定了从create
返回的相同Id(在ByteArray中(,或者我给出了NO Id,我仍然会收到这个错误。
那么问题出在哪里呢?是不是我应该寄一些挑战的东西?我的id
是必需的,但可能格式不正确?我注意到其他发送许多allowCredential
ID的示例(我不知道这些ID来自哪里,因为只有一个与原始注册中的ID匹配(。
这里有我根本缺失的东西吗?
答案看起来是(根据我所能解决的最好结果(:
Yubikey不存储凭据,因此ID(在登录过程中从服务器传回来(必须编码(加密私钥(凭据-才能交回身份验证器(Yubikey(本身。如果没有(正确地(这样做,您将收到一个错误,说密钥无法识别。由于规范允许您在get
(登录(阶段不传递任何allowCredentials
-我会假设这意味着可能有一个验证器在其上存储密钥的工具-尽管这通常不常见,(或Yubikey(?
无论哪种方式——在我的情况下,ID都必须正确地返回。我的特殊问题是,在创建期间返回的ID表示为字符串,这是base64编码的,但在编码中有一些奇怪之处,当我将其转换回get
的ArrayBuffer时,我没有完全正确。
在转换base64之前,非标准的base64格式需要替换一些字符:
thing = thing.replace(/-/g, "+").replace(/_/g, "/");