セキュリティ●●○○○

多要素認証

たようそにんしょう

知識・所持・生体の異なる要素を組み合わせる認証。パスワード漏洩だけでは破られない。

概要

多要素認証(MFA: Multi-Factor Authentication)は、認証のときに性質の異なる複数の証拠を要求する方式です。証拠は3つの系統に分類されます。本人だけが知っている「知識要素」(パスワード・PIN)、本人だけが持っている「所持要素」(スマートフォン・セキュリティキー)、本人自身である「生体要素」(指紋・顔)です。このうち異なる系統から2つ以上を組み合わせたものが多要素認証で、2つなら二要素認証(2FA)とも呼ばれます。

ポイントは「異なる系統から」という条件です。パスワードと秘密の質問はどちらも知識要素なので、2つ聞いても多要素にはなりません。攻撃者から見ると、知識は盗み聞きやデータベース漏洩で、所持物は盗難で、生体は偽造で、とそれぞれ突破の手口がまったく異なります。系統の違うものを重ねることで「1つの手口ではアカウントを落とせない」状態を作るのが MFA の本質であり、パスワードが漏れることを前提に守りを設計する、防御側の現実的な答えです。

なぜ生まれたか

長らく認証はパスワード1本に頼ってきましたが、その限界は運用の現実の中で明らかになりました。まず漏洩です。どこか1つのサービスが破られてパスワードのハッシュや平文が流出すると、多くの利用者が複数サービスで同じパスワードを使い回しているため、漏れた組を他サービスに機械的に試す「クレデンシャルスタッフィング」で被害が連鎖します。次にフィッシングです。本物そっくりの偽ログイン画面に入力させれば、どれだけ複雑なパスワードでも一瞬で盗めます。つまりパスワードは「利用者の記憶と注意力」という最も不安定なものに安全を委ねる仕組みでした。

「パスワードは漏れるもの」と認めたとき、次善の策は明快です。漏れた知識だけでは足りないように、別系統の証拠をもう1つ要求すればよい。銀行の乱数表やハードウェアトークンとして先行していたこの考え方が、スマートフォンの普及で誰もが「所持要素」を持ち歩く時代になったことで一気に一般化し、今日ではクラウドサービスや社内システムの標準装備、ゼロトラスト型のアクセス管理の前提条件になっています。

詳細

3つの要素と代表的な手段

知識要素本人だけが知っているパスワード / PIN秘密の質問漏洩・フィッシングに弱い所持要素本人だけが持っているTOTPアプリ / SMSセキュリティキー盗難・SIMスワップに注意生体要素本人自身の特徴指紋 / 顔虹彩 / 声漏れても変更できない異なる系統から2つ以上 = 多要素認証パスワード + 秘密の質問は同じ系統なので多要素ではない例: パスワード + TOTP、パスキーは所持するデバイス + そのロック解除の生体や PIN
認証の3要素 — 異なる系統を2つ以上組み合わせたものだけが多要素認証

TOTP — 共有シークレットと時刻から生まれる使い捨てコード

もっとも普及している第二要素が、認証アプリに表示される6桁のワンタイムコード、TOTP(Time-based One-Time Password)です。仕組みは意外なほど単純で、登録時に QR コードで受け渡した共有シークレット(秘密の乱数)を、サーバとアプリの両方が保管します。以後は「シークレット + 現在時刻(30秒刻み)」を HMAC というハッシュ関数の応用にかけ、結果から6桁を切り出す。両者が同じシークレットと同じ時刻を使うので、通信しなくても同じコードが独立に計算できるのです。コードは30秒で失効するため、盗み見られても再利用の窓が極めて短い。オフラインで動く点も強みです。ただし共有シークレット方式である以上、サーバ側からシークレットが漏れれば以後のコードはすべて計算されてしまいますし、後述するとおりフィッシングには耐性がありません。

「通信しないのに同じコードになる」不思議は、実際に計算過程を目で追うのが一番早いでしょう — 以下のデモで、シークレットと時刻だけから6桁が導出される様子を確かめられます。

⚡ 体験: TOTPコードを目の前で計算する
共有シークレット(Base32)
生成中…

登録時に QR コードで認証アプリへ渡される秘密がこれです。以後サーバとアプリの両方が保管し、二度と画面には出てきません。

📱 あなたの認証アプリ
--- ---15
30秒ごとに自動で次のコードへ切り替わります
計算の中身 — サーバも独立に同じ計算をしています
  1. UNIX時刻(秒)1784300925
  2. ÷30 の時刻カウンタ(8バイト16進)59,476,697 → 0x
  3. HMAC-SHA1(シークレット, カウンタ) = 20バイト計算中…
  4. 動的切り詰め: 末尾バイトの下位4ビット = 金色の4バイトを取り出し(最上位ビットは捨てる)
  5. mod 1,000,000 → 6桁……
サーバ側の検証 — 時計ズレに備えて前後1ウィンドウ(±30秒)も許容
1つ前 (T−1)--- ---現在 (T)--- ---1つ先 (T+1)--- ---

入力されたコードがこの3つのどれかに一致すればログイン成立。スマホの時計が多少ズレていても弾かない、という実務上の妥協です。

コードは「共有シークレット + 現在時刻」からその場で導出されるだけで、どこにも送信・保存されません。サーバも同じシークレットで同じ計算をするから、通信せずに照合できます。

※ 学習用のデモです。ここで生成したシークレットやコードを実際の認証に使わないでください。

一方、SMS でコードを送る方式は「電話番号を所持要素と見なす」やり方ですが、弱点が知られています。攻撃者が携帯キャリアを騙して被害者の番号を自分の SIM に移させる「SIM スワップ」が成立すると、所持要素ごと乗っ取られるからです。導入の手軽さから今も広く使われていますが、防御側としては認証アプリやセキュリティキーへの移行を促すべき方式と位置づけられています。

フィッシング耐性 — パスキーが最強とされる理由

TOTP にも見逃せない穴があります。偽サイトがパスワードと一緒に「今表示されているコードも入力してください」と促し、盗んだ値を30秒以内に本物のサイトへ中継すれば、MFA ごと突破できてしまうのです(リアルタイムフィッシング)。利用者が「どこに入力しているか」を見分けられない限り、人間の入力するコードはすべてこの手口に弱い — この課題への答えが FIDO2 / WebAuthn、そしてその利用形態であるパスキーです。

パスキーは公開鍵暗号に基づきます。登録時にデバイス内の認証器がサイトごとに鍵ペアを作り、公開鍵だけをサーバに渡します。ログイン時の往復は次のとおりです。

認証器ブラウザサーバ認証器ブラウザサーバ登録済みオリジンと一致する鍵だけを使う使い捨てのチャレンジを送るサイトのオリジンを添えて署名を依頼指紋や顔で利用者を確認チャレンジへの署名を返す署名を送信公開鍵で署名を検証してログイン成立

この方式がフィッシングに強い理由は2つあります。第一に、秘密鍵はデバイスから出ず、ネットワーク上を「入力できる秘密」が一切流れないため、盗んで中継するものが存在しません。第二に、鍵はサイトのオリジンに束縛されており、偽サイト examp1e.com からの署名依頼には example.com 用の鍵は決して応じません。「本物かどうかの見分け」を人間の注意力からブラウザと認証器の機械的な照合に置き換えたことが本質で、だからこそフィッシング耐性の観点で最強の方式とされ、パスワードそのものを置き換える「パスワードレス認証」の本命になっています。

運用の注意 — リカバリーと MFA 疲労攻撃

MFA を導入すると、今度は「所持要素を失ったときにどう本人を救うか」というリカバリー設計が急所になります。定石は、登録時に一度だけ表示するリカバリーコード(使い捨ての予備コード)を安全な場所に保管させることです。ここで復旧経路を「メールで再設定」のような弱い認証にしてしまうと、攻撃者はそこを突けばよいので、せっかくの MFA が最弱の経路のレベルまで下がってしまいます。復旧経路の強度は本経路と釣り合わせるのが原則です。

また、プッシュ通知承認型の MFA には「MFA 疲労攻撃(プッシュ爆撃)」という手口が知られています。パスワードを入手済みの攻撃者がログイン試行を繰り返して承認通知を延々と送りつけ、うんざりした本人が誤って、あるいは黙らせたい一心で「承認」を押してしまうのを狙うものです。番号照合(画面の数字を通知側で入力させる方式)の導入や、短時間の連続要求の抑止、そして怪しい承認要求を報告してもらう教育が防御側の対応になります。認証を突破された後のセッショントークンが盗まれれば MFA は関与できない、という限界も含めて、MFA は万能の壁ではなく多層防御の一枚として運用する視点が重要です。