メインコンテンツまでスキップ

FIDO Metadata Service (MDS)


概要​

FIDO Metadata Service (MDS) は、FIDO Alliance が運営する認証器メタデータの配布サービスです。

このドキュメントで学べること:

  • MDS の目的と役割
  • MDS BLOB の構造と各フィールドの意味
  • MetadataStatement の詳細
  • StatusReports による脆弱性管理
  • MDS の取得・利用方法

対象読者:

  • FIDO2 認証を実装する開発者
  • セキュリティ担当者

MDS とは​

目的と役割​

┌─────────────────────────────────────────────────────────────────────────────┐
│ FIDO Metadata Service の役割 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ 【MDS が解決する課題】 │
│ │
│ 課題 1: ルート CA 証明書の収集 │
│ ────────────────────────────────────────────────────────────────────────── │
│ - Attestation 検証には各認証器のルート CA が必要 │
│ - 認証器ベンダーは多数(Yubico, Feitian, Google, Apple, ...) │
│ - 個別に収集・管理するのは大変 │
│ → MDS が一元的に配布 │
│ │
│ 課題 2: 認証器の信頼性評価 │
│ ────────────────────────────────────────────────────────────────────────── │
│ - この認証器は FIDO 認定を受けているか? │
│ - セキュリティレベルは L1?L2?L3? │
│ - 既知の脆弱性はあるか? │
│ → MDS が認定状態と脆弱性情報を提供 │
│ │
│ 課題 3: 認証器情報の表示 │
│ ────────────────────────────────────────────────────────────────────────── │
│ - ユーザーに「どの認証器を使っているか」を表示したい │
│ - 認証器の名前、アイコンが必要 │
│ → MDS が description, icon を提供 │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

MDS の概念図​

┌─────────────────────────────────────────────────────────────────────────────┐
│ MDS のデータフロー │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ │
│ │ 認証器 │ │
│ │ ベンダー │──┐ │
│ └─────────────┘ │ │
│ ┌─────────────┐ │ メタデータ登録 │
│ │ 認証器 │──┼──────────────────┐ │
│ │ ベンダー │ │ │ │
│ └─────────────┘ │ ▼ │
│ ┌─────────────┐ │ ┌─────────────────────────┐ │
│ │ 認証器 │──┘ │ FIDO Alliance │ │
│ │ ベンダー │ │ Metadata Service │ │
│ └─────────────┘ │ │ │
│ │ - メタデータを集約 │ │
│ │ - 署名付き BLOB を生成 │ │
│ │ - 定期的に更新 │ │
│ └───────────┬─────────────┘ │
│ │ │
│ │ HTTPS で配布 │
│ ▼ │
│ ┌─────────────────────────┐ │
│ │ Relying Party (RP) │ │
│ │ │ │
│ │ - BLOB をダウンロード │ │
│ │ - 署名を検証 │ │
│ │ - AAGUID で検索 │ │
│ │ - 認証器を評価 │ │
│ └─────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

MDS BLOB の構造​

エンドポイント​

URL: https://mds3.fidoalliance.org/
Method: GET
Response: JWT (JSON Web Token)

JWT の構造​

MDS BLOB は JWT 形式で配布され、FIDO Alliance によって署名されています。

┌─────────────────────────────────────────────────────────────────────────────┐
│ MDS BLOB (JWT) の構造 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ JWT = Header.Payload.Signature │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Header (Base64URL デコード後) │ │
│ ├─────────────────────────────────────────────────────────────────────┤ │
│ │ { │ │
│ │ "alg": "ES256", // 署名アルゴリズム │ │
│ │ "typ": "JWT", │ │
│ │ "x5c": [ // 署名検証用の証明書チェーン │ │
│ │ "MIIB...", // 署名証明書 │ │
│ │ "MIIC...", // 中間 CA(オプション) │ │
│ │ ... │ │
│ │ ] │ │
│ │ } │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Payload (Base64URL デコード後) │ │
│ ├─────────────────────────────────────────────────────────────────────┤ │
│ │ { │ │
│ │ "legalHeader": "https://fidoalliance.org/...", │ │
│ │ "no": 123, // BLOB 番号(更新ごとに増加) │ │
│ │ "nextUpdate": "2025-02-01", // 次回更新予定日 │ │
│ │ "entries": [...] // 認証器メタデータの配列 │ │
│ │ } │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Signature │ │
│ ├─────────────────────────────────────────────────────────────────────┤ │
│ │ - Header.Payload を x5c[0] の秘密鍵で署名 │ │
│ │ - 検証時は x5c[0] の公開鍵を使用 │ │
│ │ - x5c の証明書チェーンを FIDO Alliance Root まで検証 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

Payload のフィールド​

フィールド型説明
legalHeaderstring法的注意事項へのリンク
nointegerBLOB のシリアル番号。更新ごとに増加
nextUpdatestring次回更新予定日(ISO 8601 形式)
entriesarray認証器メタデータの配列

entries 配列の各要素​

{
"aaguid": "ee882879-721c-4913-9775-3dfcce97072a",
"metadataStatement": {
// 認証器の詳細情報(後述)
},
"statusReports": [
// 認定状態・脆弱性情報(後述)
],
"timeOfLastStatusChange": "2024-01-15"
}
フィールド型説明
aaguidstring認証器の AAGUID(UUID 形式)
metadataStatementobject認証器のメタデータ
statusReportsarray認定状態・脆弱性レポート
timeOfLastStatusChangestring最終ステータス更新日

MetadataStatement の構造​

全体像​

┌─────────────────────────────────────────────────────────────────────────────┐
│ MetadataStatement の構造 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ { │
│ // ─────────────── 基本情報 ─────────────── │
│ "description": "YubiKey 5 Series with NFC", │
│ "icon": "data:image/png;base64,iVBORw0KGgo...", │
│ "aaguid": "ee882879-721c-4913-9775-3dfcce97072a", │
│ │
│ // ─────────────── プロトコル情報 ─────────────── │
│ "protocolFamily": "fido2", │
│ "schema": 3, │
│ "upv": [ // 対応プロトコルバージョン │
│ { "major": 1, "minor": 0 }, │
│ { "major": 1, "minor": 1 } │
│ ], │
│ "authenticatorVersion": 328966, │
│ │
│ // ─────────────── 認証アルゴリズム ─────────────── │
│ "authenticationAlgorithms": ["secp256r1_ecdsa_sha256_raw"], │
│ "publicKeyAlgAndEncodings": ["cose"], │
│ │
│ // ─────────────── セキュリティ特性 ─────────────── │
│ "keyProtection": ["hardware", "secure_element"], │
│ "matcherProtection": ["on_chip"], │
│ "cryptoStrength": 128, │
│ │
│ // ─────────────── ユーザー検証 ─────────────── │
│ "userVerificationDetails": [[...]], │
│ │
│ // ─────────────── Attestation ─────────────── │
│ "attestationTypes": ["basic_full"], │
│ "attestationRootCertificates": [ │
│ "MIID..." // ← 証明書チェーン検証に使用するルート CA │
│ ], │
│ │
│ // ─────────────── 接続方式 ─────────────── │
│ "attachmentHint": ["external", "wired", "wireless", "nfc"], │
│ "tcDisplay": [] │
│ } │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

主要フィールドの説明​

基本情報​

フィールド型説明
descriptionstring認証器の説明(表示用)
iconstringアイコン画像(Data URI 形式、PNG)
aaguidstring認証器の AAGUID

プロトコル情報​

フィールド型説明
protocolFamilystringfido2, u2f, uaf
schemaintegerメタデータスキーマのバージョン
upvarray対応する FIDO プロトコルバージョン
authenticatorVersioninteger認証器のファームウェアバージョン

セキュリティ特性​

┌─────────────────────────────────────────────────────────────────────────────┐
│ セキュリティ特性フィールド │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ 【keyProtection】 - 秘密鍵の保護方式 │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ "software" : ソフトウェアで保護(最も弱い) │ │
│ │ "hardware" : ハードウェアで保護 │ │
│ │ "tee" : Trusted Execution Environment で保護 │ │
│ │ "secure_element" : セキュアエレメントで保護(最も強い) │ │
│ │ "remote_handle" : リモートで保護 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ 【matcherProtection】 - 生体認証マッチャーの保護方式 │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ "software" : ソフトウェアで実行 │ │
│ │ "tee" : TEE 内で実行 │ │
│ │ "on_chip" : 専用チップ内で実行(最も強い) │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ 【cryptoStrength】 - 暗号強度(ビット数) │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 128 : AES-128 相当の強度 │ │
│ │ 256 : AES-256 相当の強度 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

Attestation 関連​

フィールド型説明
attestationTypesarray対応する attestation タイプ
attestationRootCertificatesarrayルート CA 証明書(Base64 DER)

attestationTypes の値:

値説明
basic_full完全な attestation(証明書チェーンあり)
basic_surrogateSelf attestation
attcaAttestation CA による署名
anonca匿名化 CA による署名
noneattestation なし

接続方式​

フィールド型説明
attachmentHintarray接続方式のヒント

attachmentHint の値:

値説明
internalプラットフォーム認証器(内蔵)
externalローミング認証器(外付け)
wired有線接続(USB)
wireless無線接続(Bluetooth)
nfcNFC 接続

StatusReports​

構造​

{
"statusReports": [
{
"status": "FIDO_CERTIFIED_L1",
"effectiveDate": "2024-01-15",
"authenticatorVersion": 328966,
"url": "https://...",
"certificationDescriptor": "FIDO2",
"certificateNumber": "FIDO20020240115001",
"certificationPolicyVersion": "1.4.0",
"certificationRequirementsVersion": "1.5.0"
}
]
}

status の値一覧​

┌─────────────────────────────────────────────────────────────────────────────┐
│ StatusReports の status 値 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ 【認定状態】 │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ NOT_FIDO_CERTIFIED : FIDO 認定を受けていない │ │
│ │ FIDO_CERTIFIED : FIDO 認定済み(レベル不明) │ │
│ │ FIDO_CERTIFIED_L1 : Level 1 認定(ソフトウェア保護) │ │
│ │ FIDO_CERTIFIED_L2 : Level 2 認定(ハードウェア保護) │ │
│ │ FIDO_CERTIFIED_L3 : Level 3 認定(高度なハードウェア保護) │ │
│ │ FIDO_CERTIFIED_L1plus : Level 1+ 認定 │ │
│ │ FIDO_CERTIFIED_L2plus : Level 2+ 認定 │ │
│ │ FIDO_CERTIFIED_L3plus : Level 3+ 認定 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ 【脆弱性・問題】 │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ USER_VERIFICATION_BYPASS : ユーザー検証がバイパス可能 │ │
│ │ ATTESTATION_KEY_COMPROMISE : Attestation 鍵が漏洩 │ │
│ │ USER_KEY_REMOTE_COMPROMISE : ユーザー鍵がリモート攻撃で漏洩可能 │ │
│ │ USER_KEY_PHYSICAL_COMPROMISE : ユーザー鍵が物理攻撃で漏洩可能 │ │
│ │ UPDATE_AVAILABLE : ファームウェア更新が利用可能 │ │
│ │ REVOKED : 認定が取り消された │ │
│ │ SELF_ASSERTION_SUBMITTED : 自己申告(未検証) │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

認定レベルの意味​

レベル鍵保護検証内容主な認証器
L1ソフトウェア基本的なセキュリティ要件ソフトウェア認証器
L2ハードウェア物理的な鍵保護YubiKey, Android
L3高度なハードウェア侵入検知、耐タンパー性高セキュリティ認証器

脆弱性対応の優先度​

status深刻度推奨アクション
REVOKED最高即座にブロック
ATTESTATION_KEY_COMPROMISE最高即座にブロック
USER_KEY_REMOTE_COMPROMISE高即座にブロック
USER_KEY_PHYSICAL_COMPROMISE中リスク評価後に判断
USER_VERIFICATION_BYPASS中警告または拒否
UPDATE_AVAILABLE低ユーザーに通知

MDS の取得と利用​

エンドポイントと取得方法​

┌─────────────────────────────────────────────────────────────────────────────┐
│ MDS BLOB の取得 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ 【エンドポイント】 │
│ URL: https://mds3.fidoalliance.org/ │
│ Method: GET │
│ Response: JWT 形式のテキスト │
│ │
│ 【取得例(curl)】 │
│ curl -o mds-blob.jwt https://mds3.fidoalliance.org/ │
│ │
│ 【レスポンス】 │
│ eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsIng1YyI6WyJNSUlD...(JWT形式) │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

JWT 署名検証​

┌─────────────────────────────────────────────────────────────────────────────┐
│ 署名検証の手順 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ 1. JWT を "." で分割 │
│ header.payload.signature │
│ │
│ 2. Header を Base64URL デコードして x5c を取得 │
│ { │
│ "alg": "ES256", │
│ "x5c": ["MIIB...", "MIIC..."] │
│ } │
│ │
│ 3. x5c[0] を X509 証明書としてパース │
│ │
│ 4. x5c の証明書チェーンを検証 │
│ - FIDO Alliance Root CA まで辿れることを確認 │
│ - FIDO Alliance Root CA は事前に入手しておく │
│ https://mds3.fidoalliance.org/pki/MDS3ROOT.crt │
│ │
│ 5. Header.Payload の署名を x5c[0] の公開鍵で検証 │
│ - alg が ES256 なら ECDSA with SHA-256 │
│ │
│ 6. 検証成功したら Payload を利用 │
│ │
│ 【注意】 │
│ - 署名検証に失敗した BLOB は使用してはいけない │
│ - 中間者攻撃により改ざんされている可能性がある │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

キャッシュ戦略​

┌─────────────────────────────────────────────────────────────────────────────┐
│ MDS キャッシュのベストプラクティス │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ 【取得頻度】 │
│ - 推奨: 日次 │
│ - MDS 自体は週次程度で更新 │
│ - ただし脆弱性情報は随時追加される │
│ │
│ 【キャッシュの構成】 │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ レイヤー 1: メモリキャッシュ │ │
│ │ - 起動時にロード │ │
│ │ - AAGUID → MetadataEntry のハッシュマップ │ │
│ │ - 高速な参照(O(1)) │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ ↑ フォールバック │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ レイヤー 2: ディスクキャッシュ │ │
│ │ - BLOB ファイルをローカルに保存 │ │
│ │ - MDS 取得失敗時のフォールバック │ │
│ │ - 再起動時の初期データ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ 【更新ロジック】 │
│ 1. nextUpdate を確認 │
│ 2. 現在日時 > nextUpdate なら新しい BLOB を取得 │
│ 3. 新しい BLOB の no が現在より大きいことを確認 │
│ 4. 署名検証後、キャッシュを更新 │
│ │
│ 【障害時の挙動】 │
│ - MDS 取得失敗: ディスクキャッシュを使用 │
│ - 署名検証失敗: 古いキャッシュを継続使用、アラート発報 │
│ - キャッシュ期限超過: 警告ログ、運用判断 │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

実装パターン​

パターン 1: 自前実装​

┌─────────────────────────────────────────────────────────────────────────────┐
│ 自前実装の流れ │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────┐ │
│ │ 1. HTTP GET │ │
│ │ mds3.fido... │ │
│ └──────────┬──────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ 2. JWT パース │ │
│ │ Header/Payload │ │
│ │ 分離 │ │
│ └──────────┬──────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ 3. x5c 証明書 │ │
│ │ チェーン検証 │ │
│ └──────────┬──────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ 4. 署名検証 │ │
│ │ (ES256) │ │
│ └──────────┬──────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ 5. Payload パース │ │
│ │ JSON → Object │ │
│ └──────────┬──────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ 6. AAGUID マップ │ │
│ │ 構築 & キャッシュ│ │
│ └─────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

パターン 2: ライブラリ利用(webauthn4j)​

webauthn4j-metadata モジュールには MDS 連携機能が含まれています。

主なクラス:

  • FidoMDS3MetadataBLOBProvider - MDS3 エンドポイントから BLOB を取得
  • LocalFileMetadataBLOBProvider - ローカルファイルから BLOB を読み込み
  • MetadataBLOBBasedTrustAnchorRepository - BLOB ベースで TrustAnchor を解決
// webauthn4j-metadata モジュールを使用した例

// MDS3 から BLOB を取得するプロバイダー
FidoMDS3MetadataBLOBProvider blobProvider = new FidoMDS3MetadataBLOBProvider(
objectConverter,
httpClient
);

// BLOB ベースの TrustAnchor リポジトリ
MetadataBLOBBasedTrustAnchorRepository trustAnchorRepository =
new MetadataBLOBBasedTrustAnchorRepository(blobProvider);

// 証明書チェーン検証に使用
DefaultCertPathTrustworthinessVerifier certPathVerifier =
new DefaultCertPathTrustworthinessVerifier(trustAnchorRepository);

📖 詳細は webauthn4j-metadata モジュール を参照してください。

パターン 3: TrustStore との連携​

MDS から取得したルート CA 証明書を TrustStore に登録するパターン。

┌─────────────────────────────────────────────────────────────────────────────┐
│ MDS → TrustStore 連携 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ 【起動時の処理】 │
│ │
│ 1. MDS BLOB を取得 & 検証 │
│ │
│ 2. 全 entries から attestationRootCertificates を抽出 │
│ │
│ 3. TrustStore(PKCS12)を生成 │
│ - 各証明書を AAGUID をエイリアスとして登録 │
│ │
│ 4. WebAuthn 検証時は通常の TrustStore として使用 │
│ │
│ 【メリット】 │
│ - 既存の証明書チェーン検証ロジックをそのまま使用可能 │
│ - MDS 障害時も TrustStore ファイルがあれば動作 │
│ │
│ 【デメリット】 │
│ - TrustStore ファイルの生成・管理が必要 │
│ - 動的な更新が難しい(再起動またはリロードが必要) │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

実装時の注意事項​

セキュリティ​

項目注意点
署名検証必須署名検証せずに MDS データを使用しない
HTTPS 必須MDS エンドポイントへのアクセスは HTTPS のみ
Root CA の管理FIDO Alliance Root CA は信頼できるソースから入手
BLOB 番号の確認古い BLOB へのロールバック攻撃を防ぐ

運用​

項目注意点
定期取得日次での取得を推奨
障害対策キャッシュによるフォールバック
監視取得失敗、署名検証失敗のアラート
ログ脆弱性検出時のログ記録

パフォーマンス​

項目注意点
キャッシュメモリキャッシュで高速化
BLOB サイズ数 MB のサイズがある(圧縮転送推奨)
パースJSON パースは起動時に1回のみ

参考リンク​