多要素認証
Multi-Factor Authentication ・ たようそにんしょう
知識・所持・生体のうち系統の違う証拠を重ねる認証。パスワードが漏れただけでは破られない。
✦ 30秒で試す — 航海パスワードが漏れても、それだけでは入られない通信できないスマホの6桁で、ログインできる?予想してみる概要
多要素認証(MFA: Multi-Factor Authentication)は、認証のときに性質の異なる複数の証拠を要求する方式です。証拠は3つの系統に分類されます。本人だけが知っている「知識要素」(パスワード・PIN)、本人だけが持っている「所持要素」(スマートフォン・セキュリティキー)、本人自身である「生体要素」(指紋・顔)です。このうち異なる系統から2つ以上を組み合わせたものが多要素認証で、2つなら二要素認証(2FA)とも呼ばれます。
ポイントは「異なる系統から」という条件です。パスワードと秘密の質問はどちらも知識要素なので、2つ聞いても多要素にはなりません。攻撃者から見ると、知識は盗み聞きやデータベース漏洩で、所持物は盗難で、生体は偽造で、とそれぞれ突破の手口がまったく異なります。系統の違うものを重ねることで「1つの手口ではアカウントを落とせない」状態を作るのが MFA の本質であり、パスワードが漏れることを前提に守りを設計する、防御側の現実的な答えです。
なぜ生まれたか
長らく認証はパスワード1本に頼ってきましたが、その限界は運用の現実の中で明らかになりました。まず漏洩です。どこか1つのサービスが破られてパスワードのハッシュや平文が流出すると、多くの利用者が複数サービスで同じパスワードを使い回しているため、漏れた組を他サービスに機械的に試す「クレデンシャルスタッフィング」で被害が連鎖します。次にフィッシングです。本物そっくりの偽ログイン画面に入力させれば、どれだけ複雑なパスワードでも一瞬で盗めます。つまりパスワードは「利用者の記憶と注意力」という最も不安定なものに安全を委ねる仕組みでした。
「パスワードは漏れるもの」と認めたとき、次善の策は明快です。漏れた知識だけでは足りないように、別系統の証拠をもう1つ要求すればよい。銀行の乱数表やハードウェアトークンとして先行していたこの考え方が、スマートフォンの普及で誰もが「所持要素」を持ち歩く時代になったことで一気に一般化し、今日ではクラウドサービスや社内システムの標準装備、ゼロトラスト型のアクセス管理の前提条件になっています。
詳細
3つの要素と代表的な手段
認証の証拠は、破られ方の違いで3つの系統に分けられます。多要素認証で数えるのは証拠の「個数」ではなく「系統」です。
TOTP — 共有シークレットと時刻から生まれる使い捨てコード
もっとも普及している第二要素が、認証アプリに表示される6桁のワンタイムコード、TOTP(Time-based One-Time Password)です。仕組みは意外なほど単純で、登録時に QR コードで受け渡した共有シークレット(秘密の乱数)を、サーバとアプリの両方が保管します。以後は「シークレット + 現在時刻(30秒刻み)」を HMAC というハッシュ関数の応用にかけ、結果から6桁を切り出す。両者が同じシークレットと同じ時刻を使うので、通信しなくても同じコードが独立に計算できるのです。コードは30秒で失効するため、盗み見られても再利用の窓が極めて短い。オフラインで動く点も強みです。ただし共有シークレット方式である以上、サーバ側からシークレットが漏れれば以後のコードはすべて計算されてしまいますし、後述するとおりフィッシングには耐性がありません。
ここで効いてくるのが時計です。スマホとサーバが同じコードを出せるのは、両者の時計が同じ30秒の区切り(窓)を指しているときだけです。実際の時計は少しずつずれるので、サーバは現在の窓だけでなく、前後1つずつの窓のコードも受け入れるのが一般的です(RFC 6238 も、通信の遅れや時計のずれを吸収するために、隣の窓を少しだけ許すことを勧めています)。許す窓を広げればずれに強くなりますが、そのぶん1つのコードが使える時間も延びます。これは使い勝手と安全性のトレードオフです。
下の部品で確かめてください。スマホの時計の針をつまんで前後にずらすと、スマホが表示するコードが変わり、サーバが受け入れる3つの窓から外れた瞬間に照合が失敗します。
JBSW Y3DP EHPK 3PXP- スマホの時刻 ÷ 30 → 窓の番号(カウンタ)
… - HMAC-SHA1(シークレット, カウンタ)= 20バイト
… - 末尾バイトの下位4ビット = … 番目から4バイトを取り出す(最上位ビットは捨てる)
… - mod 1,000,000 → 6桁
……
学習用のデモです。ここのシークレットやコードを実際の認証に使わないでください。
スマホとサーバは、同じシークレットと自分の時計だけでコードを計算しています。スマホの針をつまんで左右にずらし、コードが変わる瞬間と、サーバが受け入れる金の枠から外れる瞬間を確かめてください。
一方、SMS でコードを送る方式は「電話番号を所持要素と見なす」やり方ですが、弱点が知られています。攻撃者が携帯キャリアを騙して被害者の番号を自分の SIM に移させる「SIM スワップ」が成立すると、所持要素ごと乗っ取られるからです。米国の NIST は認証のガイドライン SP 800-63B(2017年)で、SMS などの電話網を使うコード送付を「制限付き(restricted)」の認証器に位置づけました。使ってよいが、リスクを利用者に知らせ、より強い方式への移行手段を用意せよ、という扱いです。導入の手軽さから今も広く使われていますが、防御側としては認証アプリやセキュリティキーへの移行を促すべき方式です。
フィッシング耐性 — パスキーが最強とされる理由
TOTP にも見逃せない穴があります。偽サイトがパスワードと一緒に「今表示されているコードも入力してください」と促し、盗んだ値を30秒以内に本物のサイトへ中継すれば、MFA ごと突破できてしまうのです(リアルタイムフィッシング)。利用者が「どこに入力しているか」を見分けられない限り、人間の入力するコードはすべてこの手口に弱い — この課題への答えが FIDO2 / WebAuthn、そしてその利用形態であるパスキーです。
パスキーは公開鍵暗号に基づきます。登録時にデバイス内の認証器がサイトごとに鍵ペアを作り、公開鍵だけをサーバに渡します。ログイン時の往復は次のとおりです。
この方式がフィッシングに強い理由は2つあります。第一に、秘密鍵はデバイスから出ず、ネットワーク上を「入力できる秘密」が一切流れないため、盗んで中継するものが存在しません。第二に、鍵はサイトのオリジン(CORS や同一オリジンポリシーで使うのと同じ「スキーム・ホスト・ポート」の組)に束縛されています。署名を依頼するときにオリジンを書き込むのはページではなくブラウザ自身なので、偽サイト examp1e.com からの依頼には example.com 用の鍵は決して応じません。「本物かどうかの見分け」を人間の注意力からブラウザと認証器の機械的な照合に置き換えたことが本質で、だからこそフィッシング耐性の観点で最強の方式とされ、パスワードそのものを置き換える「パスワードレス認証」の本命になっています。
組織での導入 — IdP で一括して強制する
組織で MFA を徹底するときに、アプリごとに MFA を実装して回るのは現実的ではありません。定石は、社内の各サービスのログインを IdP(ID プロバイダ)に集約し、SSO の入口で MFA を一括して要求することです。こうすると、方式の選定(SMS を禁止してパスキーや認証アプリに限る)、例外の管理、紛失時の再登録を1か所で運用でき、新しく連携したサービスにも自動で同じ強さが適用されます。逆に言えば、IdP を経由しない裏口のログイン(アプリ独自のパスワードや古いプロトコル)が残っていると、攻撃者はそこを狙います。
運用の注意 — リカバリーと MFA 疲労攻撃
MFA を導入すると、今度は「所持要素を失ったときにどう本人を救うか」というリカバリー設計が急所になります。定石は、登録時に一度だけ表示するリカバリーコード(使い捨ての予備コード)を安全な場所に保管させることです。ここで復旧経路を「メールで再設定」のような弱い認証にしてしまうと、攻撃者はそこを突けばよいので、せっかくの MFA が最弱の経路のレベルまで下がってしまいます。復旧経路の強度は本経路と釣り合わせるのが原則です。
また、プッシュ通知承認型の MFA には「MFA 疲労攻撃(プッシュ爆撃)」という手口が知られています。パスワードを入手済みの攻撃者がログイン試行を繰り返して承認通知を延々と送りつけ、うんざりした本人が誤って、あるいは黙らせたい一心で「承認」を押してしまうのを狙うものです。番号照合(画面の数字を通知側で入力させる方式)の導入や、短時間の連続要求の抑止、そして怪しい承認要求を報告してもらう教育が防御側の対応になります。認証を突破された後のセッションの Cookie やアクセストークンが盗まれれば MFA は関与できない、という限界も含めて、MFA は万能の壁ではなく多層防御の一枚として運用する視点が重要です。
試問
認証アプリの6桁のコード(TOTP)は、共有した秘密の値と「いまが何番目の30秒か(窓)」から、スマホとサーバがそれぞれ計算します。図には時刻の窓が横に並び、サーバの時計の線は固定、スマホの時計の針は左右にドラッグしてずらせます。金の枠が、サーバがいまコードを受け入れる範囲です。
JBSW Y3DP EHPK 3PXP- スマホの時刻 ÷ 30 → 窓の番号(カウンタ)
… - HMAC-SHA1(シークレット, カウンタ)= 20バイト
… - 末尾バイトの下位4ビット = … 番目から4バイトを取り出す(最上位ビットは捨てる)
… - mod 1,000,000 → 6桁
……
学習用のデモです。ここのシークレットやコードを実際の認証に使わないでください。
スマホとサーバは、同じシークレットと自分の時計だけでコードを計算しています。スマホの針をつまんで左右にずらし、コードが変わる瞬間と、サーバが受け入れる金の枠から外れる瞬間を確かめてください。
