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

FIDO2/WebAuthn パフォーマンス分析


概要

FIDO2/WebAuthnは公開鍵暗号を使用するため、パスワード認証と比較して異なるパフォーマンス特性を持ちます。本ドキュメントでは、FIDO2認証のパフォーマンス特性、CPU負荷の要因、最適化手法について解説します。


FIDO2認証フローとCPU負荷

認証フローの構成

┌─────────────────────────────────────────────────────────────────────┐
│ FIDO2認証フロー │
├─────────────────────────────────────────────────────────────────────┤
│ 1. Challenge Request → ランダムチャレンジ生成 │
│ 2. Assertion Generation → クライアント側ECDSA署名(軽量) │
│ 3. Authentication Verify → サーバー側ECDSA署名検証(CPU負荷高) │
└─────────────────────────────────────────────────────────────────────┘

CPU負荷が高い処理

1. ECDSA署名検証(最もCPU負荷が高い)

サーバー側で行われるECDSA署名検証が、FIDO2認証で最もCPU負荷が高い処理です。

クライアント                           サーバー
│ │
│ assertion(署名付き) │
│ ─────────────────────────────────→ │
│ │
│ ┌─────────┴─────────┐
│ │ ECDSA署名検証 │
│ │ - P-256曲線 │
│ │ - 楕円曲線点乗算 │
│ │ - 計算コスト高 │
│ └─────────┬─────────┘
│ │
│ 認証結果 │
│ ←───────────────────────────────── │

処理内容:

  • クライアントから送信されたアサーションの署名を検証
  • P-256(secp256r1)曲線でのECDSA検証
  • 楕円曲線上の点乗算が必要で計算コストが高い

2. チャレンジ生成

// SecureRandomによる32バイトのランダム生成
byte[] challenge = new byte[32];
secureRandom.nextBytes(challenge);

処理内容:

  • 暗号学的に安全なランダムバイト生成
  • エントロピープール枯渇時に遅延する可能性

3. CBOR/JSONパース

処理内容:

  • クライアントからのJSON/CBORデータのパース
  • AuthenticatorDataのデコード
  • Base64URLエンコード/デコード

高負荷時の挙動

リクエストキューイング

サーバーの処理能力を超えるリクエストが来ると、キューイングが発生します。

┌─────────────────────────────────────────────────────────────────────┐
│ Webアプリケーションサーバー │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ リクエスト → [接続キュー] → [ワーカープール] → [アプリケーション処理] │
│ ↑ ↑ │
│ キュー上限 ワーカー数上限 │
│ │
│ ワーカーが全てビジー → キューで待機 → レイテンシ増加 │
│ キューも満杯 → 接続拒否(503等) │
│ │
└─────────────────────────────────────────────────────────────────────┘

一般的な構成要素:

要素説明
接続キューワーカーが空くまでリクエストを待機させる
ワーカープール同時に処理できるリクエスト数の上限
タイムアウトキュー待ち時間の上限

挙動:

  1. リクエスト到着時、空きワーカーがあれば即座に処理開始
  2. 全ワーカーがビジーの場合、接続キューで待機
  3. キューも満杯になると接続拒否またはタイムアウト

Little's Law

L = λ × W

L: システム内の平均リクエスト数
λ: スループット(req/sec)
W: 平均レイテンシ

スループットが飽和すると、同時リクエスト数の増加分だけレイテンシが増加します。

全ステップが均等に遅くなる現象

高負荷時に「FIDO2検証だけでなく全ステップが遅くなる」場合、それはFIDO2固有の問題ではなく、サーバー全体のCPU飽和によるキューイングが原因です。


他の認証方式との比較

パスワード認証との比較

項目パスワード認証FIDO2認証
サーバー側処理bcrypt/Argon2ハッシュ比較ECDSA署名検証
CPU負荷特性意図的に重くしている暗号処理として必要な負荷
調整可能性コストファクターで調整可固定(アルゴリズム依存)
スケール特性ハッシュ計算がボトルネック署名検証がボトルネック

注意: bcryptのコストファクター設定によっては、パスワード認証の方が重い場合もあります。


最適化手法

1. 水平スケーリング

FIDO2認証はステートレスなため、インスタンス追加で線形にスケール可能です。

# docker-compose.yml
services:
idp-server:
deploy:
replicas: 4 # インスタンス数を増加

2. WebAuthnManagerのシングルトン化

リクエストごとにWebAuthnManagerを生成している場合、シングルトン化で初期化コストを削減できます。

// 毎回生成(非効率)
public void authenticate(...) {
WebAuthnManager manager = WebAuthnManager.createNonStrictWebAuthnManager();
}

// シングルトン化(効率的)
private static final WebAuthnManager MANAGER =
WebAuthnManager.createNonStrictWebAuthnManager();

3. 非同期処理の活用

クリティカルパスにない処理を非同期化:

  • 監査ログの記録
  • 統計情報の更新
  • セキュリティイベントの発行
@Async
public void recordAuditLog(AuthenticationEvent event) {
// 非同期で監査ログを記録
}

4. コネクションプール最適化

データベースコネクションプールを適切に設定:

spring:
datasource:
hikari:
maximum-pool-size: 20
minimum-idle: 10

5. ハードウェア最適化

  • CPU: 十分なコア数の確保
  • AES-NI: 暗号処理のハードウェアアクセラレーション
  • エントロピー: /dev/urandomの使用(Linuxの場合)

ボトルネック特定方法

1. リソースモニタリング

# Docker環境の場合
docker stats

確認項目:

  • CPU使用率が80%を超えていないか
  • メモリ不足が発生していないか

2. PostgreSQLクエリ分析

-- pg_stat_statements拡張を有効化
CREATE EXTENSION pg_stat_statements;

-- 統計リセット
SELECT pg_stat_statements_reset();

-- テスト実行後、遅いクエリを確認
SELECT
LEFT(query, 80) as query_preview,
calls,
ROUND(mean_exec_time::numeric, 2) as avg_ms,
ROUND((total_exec_time / SUM(total_exec_time) OVER() * 100)::numeric, 1) as pct
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;

3. 判断フローチャート

全ステップが均等に遅い?

├─ Yes → サーバーCPU飽和(スケールアウトが必要)

└─ No → 特定ステップだけ遅い

├─ DB関連 → クエリ最適化、インデックス追加

└─ 暗号処理 → ハードウェアアクセラレーション検討

容量計画

必要スループットの算出

必要スループット = ピーク時同時ユーザー × 認証頻度 / 時間

例: 10,000ユーザー、1時間に1回認証
= 10,000 / 3600 ≈ 2.8 req/sec

安全マージン(3倍)を考慮: 8.4 req/sec

推奨指標

指標推奨値
認証レイテンシ (p95)< 500ms
サーバーCPU使用率< 70%
エラー率< 0.1%

まとめ

  1. FIDO2で最もCPU負荷が高いのはECDSA署名検証
  2. 高負荷時に全ステップが遅くなるのはキューイングが原因
  3. 水平スケーリングが最も効果的な対策
  4. ボトルネック特定にはリソースモニタリングとクエリ分析が重要

関連ドキュメント