こんにちは、富士榮です。
先日、いろいろな認証器でパスキー登録をしてみましたが、レスポンスの中のフラグをどうやって取得するの?というあたりについて細かく解説していないの今回解説していきたいと思います。
navigator.credentials.create()メソッドの返却値の定義がこちらのドキュメントにあります。
https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer/create#return_value_2
定義によると、PublicKeyCredentialが返されるようですね。
A Promise that resolves with an PublicKeyCredential instance matching the provided parameters. If no credential object can be created, the promise resolves with null.
では、PuiblicKeyCredentialの定義を見ていきましょう。
https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredential
以下のメンバが含まれます。
- PublicKeyCredential.authenticatorAttachment
- PublicKeyCredential.id
- PublicKeyCredential.rawId
- PublicKeyCredential.response
- PublicKeyCredential.type
上記のうち、PublicKeyCredential.responseの中に各種フラグなどが格納されます。
このresponseはAuthenticatorAttestationResponse(AuthenticatorResponseから継承)にはgetAuthenticatorData()というメソッドがあり、認証器のデータを取得できます。
このメソッドは最低37バイトからなるArrayBufferであるAuthenticator dataという形式のデータを返却します。
回りくどかったですが、このAuthenticator Dataの中に欲しい情報が入っています。
先に書いた通り、この返却値はArrayBufferで、
- rpIdHash (32 bytes)
- flags (1 bytes)
- signCount (4 bytes)
- attestedCredentialData (variable length)
- extensions (variable length)
という構造になっています。
先日のポストではこの33バイト目にあるflagsの値を見ていたわけです。
flagsの値を再掲しますが、この1バイトの中の各ビットが認証器が使用されたときの状態を表しています。
この辺りをコードで表すとこんな感じになります。
まずはcreate()を行います。
// ブラウザAPIの呼び出し
const cred = await navigator.credentials.create({
publicKey: options,
});
フラグの値を取得します。
const flags = new DataView(cred.response.getAuthenticatorData()).getUint8(32).toString();
$("#userPresence").text("User Presence(UP) : "+ ((Number(flags) & 1)? 'Yes': 'No'));
$("#userVerification").text("User Verification(UV) : "+ ((Number(flags) & 4)? 'Yes': 'No'));
$("#backupEligibility").text("Backup Eligibility(BE) : "+ ((Number(flags) & 8)? 'Yes': 'No'));
$("#backupState").text("Backup State(BS) : "+ ((Number(flags) & 16)? 'Yes': 'No'));
$("#attestedCredentialData").text("Attested Credential Data(AT) : "+ ((Number(flags) & 64)? 'Yes': 'No'));
$("#extensionData").text("Extension Data(ED) : "+ ((Number(flags) & 128)? 'Yes': 'No'));
getUint8の引数で32バイトオフセットすることでflagsのところまで辿りつけるので、その値をNumber化した上で各ビット単位で論理和をとって状態を取得しています。
ざっとこんな感じでフラグを取得していました、という種明かしでした。
0 件のコメント:
コメントを投稿