ritouです。
定期ってつけてるぐらいいつも言ってることなのですが、公開鍵暗号方式にしたらフィッシング対策もできてすんばらしいみたいな表現には反対です。
何が課題なのか
パスワード認証とフィッシング攻撃における課題はいくつかあります。
フィッシングサイトにパスワードそのものが盗まれ、それを使ってログインされてしまう (クレデンシャルスタッフィング)
フィッシングサイトの中継により、ログインセッションが盗まれてしまう(MiTM, AiTM)
OTP、TOTP、認証アプリなどの認証を追加してもやられてしまう
前者については明示的ですね。そもそもSMS OTPは認証イベントに紐づいていますし、TOTPは時間に紐づけられています。なので前者のような再利用の課題へは元から対策されているとも言えます。Webアプリケーションやネイティブアプリが正規なものに対してのみパスワードが入力されるような仕組みが必要とされていたわけです。
公開鍵暗号方式(具体的には署名)を使うことで解決できること
公開鍵暗号方式の仕組みを認証に適用する場合、おおまかに次のような流れとなります。
サービスはチャレンジの値を含むデータを作成してユーザーに認証要求
チャレンジを含むデータに対してユーザー側で保持している秘密鍵を用いて署名を生成してサービスに渡す
サービスが保持している公開鍵を用いて署名を検証し、チャレンジの値を検証してOKならばログインさせる
このような仕組みにより、上記のフィッシング攻撃の課題をどう解決できるか、ということを考えてみます。
フィッシングサイトにパスワードそのものが盗まれ、それを使ってログインされてしまう (クレデンシャルスタッフィング)
署名生成のキモである秘密鍵の値は通信路を流れません。さらに、チャレンジレスポンスの仕組みが導入されている場合はフィッシングサイトが受け取った署名の値の再利用は困難です。そのため、こちらの課題への対策はされていると考えても良いでしょう。
フィッシングサイトの中継により、ログインセッションが盗まれてしまう(MiTM, AiTM)
問題はこっちですよね。プロキシのようにそのまま正規サービスの画面を中継することでセッションを狙いにくる攻撃に対して、署名を渡してしまったらそのままログイン成功してしまうでしょう。メタデータを持てる証明書を利用するとなると変わる話もあるかもしれませんが公開鍵暗号方式、署名の基本的な仕組みだけではこの課題への対策はできないと認識しておくべきです。
フィッシング耐性を持つためには
Webアプリケーションやネイティブアプリが正規なものに対してのみパスワードが入力されるような仕組みが必要とされていたわけです。
繰り返しになりますが、正規のサービスに対して正規のサービスのパスワードが入力される、正規のサービスに対して正規のサービス向けの秘密鍵で生成された署名が渡される必要があります。
これまでのパスワードマネージャーでは、アクセス中のURLをパスワードマネージャーが独自のロジックで解析して参照するパスワードを絞ります。パスキー、というかWebAuthnではサービスが指定するRP ID(ドメインやオリジンの値)が現在アクセスしているURLに(完全もしくは部分)一致しているかをブラウザが判断し、さらにサービスに渡されたデータにもどのRP IDに対する認証結果なのかが含まれるためにサービス側で検証可能です。これが "フィッシング耐性" の正体なのです。
まとめ
フィッシング攻撃に関する課題はいくつかある
公開鍵暗号方式、署名生成と検証の仕組みで対策できるものとできないものがある
正規のサービスのみにクレデンシャルの値や認証結果を渡せることが重要であり、それは公開鍵暗号方式の機能とは別ものと捉えるのが良さそう
今後も何度でも「定期」をつけて言い続けますので皆さんも意識してもらえると世の中が平和になるでしょう。
ではまた。