FIDO URI

QRコードをデコードするとFIDOで始まるURIが得られます。 例えば次のFIDO URIはGithubにパスキー認証でログインしようとしたときに得られたものです。ただし、このFIDO URIはすでに期限が切れているため無効です。

FIDO:/144519942798050940878582488612106138031714230513094139379299368895081878828178926639100664952474023496122943190653681470073382838502067711648524250383106107096654083332

このリポジトリでは、ウェブサイトにパスキー認証でログインしようとしたときに表示されるQRコードをデコードするためのPythonコードを提供しています。

ハイブリッドトランスポート

パスキー認証でログインしようとしたときにQRコードが表示される場合があります。これは、パスキー対応のローミング認証器とハイブリッドトランスポートにより通信しようとしているからです。ハイブリッドトランスポートは FIDO 2.2 から導入されました。

ローミング認証器との通信にはUSB、Wi-Fi、Bluetooth LEが使われますが、他の通信方法としてQRコードの読み取りのような追加のトランスポートも許容するようになりました。

FIDO URIのエンコード方式

FIDO:/ の部分は英数字モードでエンコードされ、残りの数字列の部分は数字モードでエンコードされます。これにより、できるだけ小さなQRコードを生成することを意図しています。

数字の部分はバイナリデータをエンコードしたもので、そのエンコードとデコードのためのコードがdigits_decode.pyおよびdigits_encode.pyです。この符号化方法には特に名前が付けられていませんが、7バイトを17文字の数字で表現します。

FIDO URIの数字部分をデコードするとCBORシリアライズされた認証情報が得られます。

デコード例

import cbor2
decoded : dict = cbor2.loads(decoded_bytes)

デコードされたCBORオブジェクトの説明

{
  0: b'\x03X3ebeC\xa96\x1f\xc6\xad\xe8\x80\xa4\x1d\x87\xa4\xe6\xca2y\x841\xd79\xfd\xbd\xd7\xbfBH\xb6',
  1: b'\xc5\\\x02S\x86\xa58\x9e\xad+\x05\x1b7\xbci\x9b',
  2: 2,
  3: 1715823145,
  4: True,
  5: 'ga'
}

キーと対応する値の詳細

  1. キー 0 (33バイトの圧縮公開鍵)

    • : b'\x03X3ebeC\xa96\x1f\xc6\xad\xe8\x80\xa4\x1d\x87\xa4\xe6\xca2y\x841\xd79\xfd\xbd\xd7\xbfBH\xb6'
    • 説明: 33バイトのP-256, X9.62形式の圧縮公開鍵。
  2. キー 1 (16バイトのランダムQR秘密鍵)

    • : b'\xc5\\\x02S\x86\xa58\x9e\xad+\x05\x1b7\xbci\x9b'
    • 説明: 16バイトのランダムなQR秘密鍵。
  3. キー 2 (トンネルサーバードメインの数)

    • : 2
    • 説明: 実装が知っているトンネルサーバードメインの数。
  4. キー 3 (エポック秒での現在時刻)

    • : 1715823145
    • 説明: 2024年5月15日 23:05:45 UTCに対応するエポック秒での時刻。
  5. キー 4 (状態アシスト取引の可能性)

    • : True
    • 説明: デバイスが状態アシスト取引を行えることを示すブール値。
  6. キー 5 (取引タイプのヒント)

    • : 'ga'
    • 説明: 次にgetAssertionが続くことを示すヒント。このヒントはユーザーにすぐにガイダンスを提供するためのものです。