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

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回のみ

参考リンク