-
-
Save daisukenishino2/f09fb400fa2186aead4b6f8cad59ab38 to your computer and use it in GitHub Desktop.
{ | |
"rp": { | |
"id": "localhost", | |
"name": "Fido2 test" | |
}, | |
"user": { | |
"name": "aaa@example.com", | |
"id": "YWFhQGV4YW1wbGUuY29t", | |
"displayName": "Display aaa@example.com" | |
}, | |
"challenge": "U8iy6iV6nyXjWph2he3KwA", | |
"pubKeyCredParams": [ | |
{ | |
"type": "public-key", | |
"alg": -7 | |
}, | |
{ | |
"type": "public-key", | |
"alg": -257 | |
}, | |
{ | |
"type": "public-key", | |
"alg": -37 | |
}, | |
{ | |
"type": "public-key", | |
"alg": -35 | |
}, | |
{ | |
"type": "public-key", | |
"alg": -258 | |
}, | |
{ | |
"type": "public-key", | |
"alg": -38 | |
}, | |
{ | |
"type": "public-key", | |
"alg": -36 | |
}, | |
{ | |
"type": "public-key", | |
"alg": -259 | |
}, | |
{ | |
"type": "public-key", | |
"alg": -39 | |
}, | |
{ | |
"type": "public-key", | |
"alg": -65535 | |
} | |
], | |
"timeout": 60000, | |
"attestation": "none", | |
"authenticatorSelection": { | |
"requireResidentKey": false, | |
"userVerification": "preferred" | |
}, | |
"excludeCredentials": [], | |
"extensions": { | |
"exts": true, | |
"uvi": true, | |
"loc": true, | |
"uvm": true, | |
"biometricPerfBounds": { | |
"FAR": 3.40282347e+38, | |
"FRR": 3.40282347e+38 | |
} | |
}, | |
"status": "ok", | |
"errorMessage": "" | |
} |
{ | |
"id": "XgQL5lEqNiwJjR20PbJ2jeohu_C9IU8a03umfcXaHpF8qz_7oZx9bPgViOMWm7J7RaZYCo_oglDbDenGfwd5IA", | |
"rawId": "XgQL5lEqNiwJjR20PbJ2jeohu_C9IU8a03umfcXaHpF8qz_7oZx9bPgViOMWm7J7RaZYCo_oglDbDenGfwd5IA", | |
"type": "public-key", | |
"extensions": {}, | |
"response": { | |
"AttestationObject": "o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVjESZYN5YgOjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2NBAAAAOwAAAAAAAAAAAAAAAAAAAAAAQF4EC-ZRKjYsCY0dtD2ydo3qIbvwvSFPGtN7pn3F2h6RfKs_-6GcfWz4FYjjFpuye0WmWAqP6IJQ2w3pxn8HeSClAQIDJiABIVggZYp4zvvIsAa45MBTfKoDArfr9G4JslQzHNBQiHoiIEQiWCA7Cs8aAvbCGX6IjPOf0zV8E7ynD-01sKg8boDbr4kLRQ", | |
"clientDataJson": "eyJjaGFsbGVuZ2UiOiJVOGl5NmlWNm55WGpXcGgyaGUzS3dBIiwib3JpZ2luIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQzMjkiLCJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIn0" | |
} | |
} |
{ | |
"result": { | |
"publicKey": "pQECAyYgASFYIGWKeM77yLAGuOTAU3yqAwK36_RuCbJUMxzQUIh6IiBEIlggOwrPGgL2whl-iIzzn9M1fBO8pw_tNbCoPG6A26-JC0U", | |
"user": { | |
"name": "aaa@example.com", | |
"id": "YWFhQGV4YW1wbGUuY29t", | |
"displayName": "Display aaa@example.com" | |
}, | |
"credType": "none", | |
"aaguid": "00000000-0000-0000-0000-000000000000", | |
"credentialId": "XgQL5lEqNiwJjR20PbJ2jeohu/C9IU8a03umfcXaHpF8qz/7oZx9bPgViOMWm7J7RaZYCo/oglDbDenGfwd5IA==", | |
"counter": 59, | |
"status": null, | |
"errorMessage": null | |
}, | |
"status": "ok", | |
"errorMessage": "" | |
} |
aaa@example.com (FormData) |
{ | |
"challenge": "w9PA4LdyXmYeYgC12J6_6Q", | |
"timeout": 60000, | |
"rpId": "localhost", | |
"allowCredentials": [ | |
{ | |
"type": "public-key", | |
"id": "XgQL5lEqNiwJjR20PbJ2jeohu_C9IU8a03umfcXaHpF8qz_7oZx9bPgViOMWm7J7RaZYCo_oglDbDenGfwd5IA" | |
} | |
], | |
"userVerification": "discouraged", | |
"extensions": { | |
"appid": "https://localhost:44329", | |
"txAuthSimple": "FIDO", | |
"txAuthGenericArg": { | |
"contentType": "text/plain", | |
"content": "RklETw==" | |
}, | |
"uvi": true, | |
"loc": true, | |
"uvm": true | |
}, | |
"status": "ok", | |
"errorMessage": "" | |
} |
{ | |
"id": "XgQL5lEqNiwJjR20PbJ2jeohu_C9IU8a03umfcXaHpF8qz_7oZx9bPgViOMWm7J7RaZYCo_oglDbDenGfwd5IA", | |
"rawId": "XgQL5lEqNiwJjR20PbJ2jeohu_C9IU8a03umfcXaHpF8qz_7oZx9bPgViOMWm7J7RaZYCo_oglDbDenGfwd5IA", | |
"type": "public-key", | |
"extensions": { | |
"appid": false | |
}, | |
"response": { | |
"authenticatorData": "SZYN5YgOjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2MBAAAAPQ", | |
"clientDataJson": "eyJjaGFsbGVuZ2UiOiJ3OVBBNExkeVhtWWVZZ0MxMko2XzZRIiwibmV3X2tleXNfbWF5X2JlX2FkZGVkX2hlcmUiOiJkbyBub3QgY29tcGFyZSBjbGllbnREYXRhSlNPTiBhZ2FpbnN0IGEgdGVtcGxhdGUuIFNlZSBodHRwczovL2dvby5nbC95YWJQZXgiLCJvcmlnaW4iOiJodHRwczovL2xvY2FsaG9zdDo0NDMyOSIsInR5cGUiOiJ3ZWJhdXRobi5nZXQifQ", | |
"signature": "MEUCIAOzC-3dbiDcyZtlIEP39EOctwQNe8XMXNtqKs71fOi3AiEAsOiKJr_qF7oCsDuYlAYdaN_nDot1EAAAwykbF-B8aXg" | |
} | |
} |
{ | |
"credentialId": "XgQL5lEqNiwJjR20PbJ2jeohu/C9IU8a03umfcXaHpF8qz/7oZx9bPgViOMWm7J7RaZYCo/oglDbDenGfwd5IA==", | |
"counter": 61, | |
"status": "ok", | |
"errorMessage": "" | |
} |
ちょっと疑問(ArrayBuffer と Uint8Array)
概要
2. Parameter of navigator.credentials.create()の直前で、
- $.challenge
- $.allowCredentials.id
を、ArrayBufferではなく、Uint8Arrayに変換しているが、
Uint8ArrayだとJSON.stringify() したとき、少々、冗長な出方になる。
確認
このため、webauthn.jsに定義されている、coerceToArrayBuffer関数を使用するように処理を変更して、問題なく動作するか、動作検証してみることにした。
コードの修正
const challenge = makeAssertionOptions.challenge.replace(/-/g, "+").replace(/_/g, "/");
makeAssertionOptions.challenge = Uint8Array.from(atob(challenge), c => c.charCodeAt(0));
makeAssertionOptions.allowCredentials.forEach(function (listItem) {
var fixedId = listItem.id.replace(/\_/g, "/").replace(/\-/g, "+");
listItem.id = Uint8Array.from(atob(fixedId), c => c.charCodeAt(0));
});
↓ ↓ ↓
const challenge = makeAssertionOptions.challenge.replace(/-/g, "+").replace(/_/g, "/");
//makeAssertionOptions.challenge = Uint8Array.from(atob(challenge), c => c.charCodeAt(0));
makeAssertionOptions.challenge = coerceToArrayBuffer(challenge);
makeAssertionOptions.allowCredentials.forEach(function (listItem) {
var fixedId = listItem.id.replace(/\_/g, "/").replace(/\-/g, "+");
//listItem.id = Uint8Array.from(atob(fixedId), c => c.charCodeAt(0));
listItem.id = coerceToArrayBuffer(fixedId);
});
出力の確認
適切に動作し、出力も以下の様になった。
{
"challenge": {ArrayBuffer(16)},
"timeout": 60000,
"rpId": "localhost",
"allowCredentials": [
{
"type": "public-key",
"id": {ArrayBuffer(64)}
}
],
"userVerification": "discouraged",
"extensions": {
"appid": "https://localhost:44329",
"txAuthSimple": "FIDO",
"txAuthGenericArg": {
"contentType": "text/plain",
"content": "RklETw=="
},
"uvi": true,
"loc": true,
"uvm": true
},
"status": "ok",
"errorMessage": ""
}
結論
Credential Management API(navigator.credentials...)のBufferSourceの引数は、
- Uint8Arrayでも、
- Uint8Array.bufferの返すArrayBufferでも、
どちらでも適切に動作するもよう。
因みに、BufferSourceとは、
4.2. BufferSource
typedef (ArrayBufferView or ArrayBuffer) BufferSource;
...良く解らん。
ちょっと疑問(2つ以上のカギの登録)
概要
fido2-net-libのストア設計を見ると、
公開鍵が複数登録可能に見えるが本当か?
確認
重複登録
認証器を重複して登録仕様とすると、
FIDO2Serverは、excludeCredentialsに以下の様に値を設定する。
"excludeCredentials": [
{
"type": "public-key",
"id": "xzJdD_Fl8_MlGjM00owaGLIdAklEnNktohB5wuaylsWlzAxbuOcIks7eXN4yVFy4or1ZyVKCgEAv6iSGNqOJAg"
}
],
例外発生
この公開鍵は、当該認証器が生成したものであると判別できるようで、Chromeのnavigator.credentials.create()メソッドから「The user attempted to register an authenticator that contains one of the credentials already registered with the relying party.」というメッセージが返される。
結論
異なる認証器を使用すれば、
2つ以上のカギを登録可能であるため、
削除処理はリスト形式にする必要がある。
※ ただし、Googleなんかは1つしか登録できない(Microsoftは不明)。
追加の情報 (2019/03/01)
テスト画面に色々追加がされているのでそれぞれのパラメタがなんなのか?纏めた。
![image](https://user-images.githubusercontent.com/7278770/53621982-b6da2f00-3c3b-11e9-8353-c43d930cf4c6.png)
navigator.credentials.create() の param
など、詳しくはコチラを参照。
Attestation Type
Authenticator Type
以下の様に以下の値を設定する ( enum AuthenticatorAttachment )。
authenticatorSelection = { "authenticatorAttachment":"platform" }
Resident Credentials
authenticatorSelection = { "requireResidentKey": true }
navigator.credentials.get() の param
など、詳しくはコチラを参照。
User Verification