created_at
updated_at
tags
toc

Passkey への道 #5: 2FA/WebAuthn

Intro

Infostealer は、ユーザの権限でインストールされ、ユーザがアクセスできるあらゆる情報を盗んで去っていく。

そこから、どんなに暗号化して保存しても、使用時には平文にしないといけない「パスワード」という文字列を守り抜くのは非常に難しい。

であれば、最初から文字列に頼らなければ良い。それが WebAuthn と FIDO だった。

Authenticator

会社で、このようなデバイスを配られた人もいるかもしれない。

YubiKey

このメモリースティックのようなデバイスは、Security Key と呼ばれ、内部に取り出せない秘密鍵を保存している。

TOTP 用のデバイスと同じように秘密鍵を持っているが、乱数を表示するのではなく、この中にある秘密鍵そのもので認証を行うためのものだ。「所有」の要素であるため、社員証につけて首から下げている人もいるかもしれない。

こうしたデバイスで認証するために、ブラウザには WebAuthn という API が標準化されている。デバイスを USB ポートに差し込み、サイトに登録する。ログイン時は、金属部分をタップすればログインできるのだ。

TOTP とやっていることは非常に近いが、「文字列を入力する」という行為がない分、こちらの方式のほうが安全と言える。

WebAuthn は、明示的に API を呼び出さなければ認証できない上に、ドメインが変われば反応しない。対応するサービスは、登録と利用でドメインが変わるといった実装ができないのだ。

物理的に盗まれれば別だが、例えば指した USB ポートを経由して中の鍵を吸い出したり、すれ違いざまに鍵をスキャンするといった攻撃もできないよう設計されている。無理に開けて取り出そうとすれば、鍵が消えて壊れるという、耐タンパー性を持っている。

これを二要素認証に用いれば、TOTP よりもよっぽど堅牢な作りになるのだ。

しかし、情シスがしっかりした企業で配られて使っている社員か、セキュリティ意識の高くてわざわざ購入する少数のユーザがいるだけで、一般ユーザまで広く普及し、みんなが 1 つは持っているという状態にはならなかった。

何より人間は、こういったものを簡単に無くすし、簡単に壊す。登録できる鍵の数も制限があるため、しっかり使うと一個では足りなくなる。決して扱いやすいものではなかった。

転機が訪れたのは、やはりスマホの対応だ。WebAuthn の API に反応し、スマホ内部に秘密鍵を生成できるようになったのだ。これを Platform Authenticator などと呼ぶ。

スマホであればすでに普及し、みんなが肌身離さず持ち歩いている。容量も格段に多く、単体デバイスよりは壊れにくい。ユーザさえその気になれば普及するための基盤は整っていた。

しかし、普及の足かせとして、リカバリの問題が無視できなかった。

2FA のリカバリ

実は TOTP でもそうなのだが、リカバリはユーザにとって非常に重要な問題だ。

パスワードを忘れたユーザは、メールアドレスでリカバリできるのが一般的だ。もしここで、TOTP や WebAuthn を登録したスマホを無くしたら、そのユーザはどうリカバリすべきだろうか?

もしここで、メールアドレスで TOTP/WebAuthn をリカバリできるとなれば、それは正規化するとメールで入っている単要素に集約される。メールが盗まれた時に、両方とも突破できるなら 2FA としての効能が薄い。

そこで、TOTP/WebAuthn を登録したユーザには、通常以下のような乱数列が表示され、それを保存するように促される。これが「バックアップコード」と呼ばれるものだ。

adsff-aoeif
xpvge-fiqle
o438d-fo2de
...
...

もしスマホを忘れたり、壊れたりして、TOTP/WebAuthn ができなくなったら、このバックアップコードのうち 1 つを入力すれば、2FA を通ることができる。

問題は、多くの一般ユーザにとって「これが何なのか」を理解するのが難しかったり、わかっていてもどう管理すればいいのかわからない状態で、2FA の登録だけが推し進められてしまったことだ。

エンジニアの中にも、GitHub が TOTP に対応したとき、進められるまま Google Authenticator を入れたが、バックアップコードをスマホ内にダウンロードしたまま放置し、スマホが壊れた時に GitHub に入れなくなったという人がちらほら出た。

そう、多くの人は「バックアップコード」など見向きもしないか、一応スマホの中にダウンロードしてそのままなのだ。その状態でスマホが壊れたり、機種変してしまうと、TOTP/WebAuthn は詰んでしまう。

銀行や保険のように、本人確認という最終手段が使えたり、GitHub のように登録した SSH の鍵で確認できるサービスは良いが、そうでない一般サービスには「アカウントの乗っ取り」を防ぐためにリカバリプロセスが実施できなければ、安全側に倒すため「救済しない」ものもある。そのあたりが、機種変しても TOTP が途絶えないように、Authenticator アプリを入れさせるよりも、SMS に送りつけることを選び続けるサイトが残る理由でもあるだろう。

パスワードマネージャの場合

ちなみに、Google Authenticator の TOTP の鍵は、スマホのローカルに生成され取り出せないため、扱いは YubiKey などの Authenticator と近いものだ。

機種変更するには、新しい機種で登録し直してから古い機種を処分するなど、適切な移行プロセスを行う必要がある。ここで、100 個の TOTP が登録されていたら、移行前に 100 回登録のし直しが必要になる。

一方、Authy というアプリは、TOTP をクラウドで同期できるため、新しい機種で Authy にログインさえすれば、端末の移行や複数端末の併用は圧倒的に楽になる。筆者も昔は Authy を使っていた。

後にパスワードマネージャが TOTP に対応し、同じように同期がクラウドを介して行えるようになったのは画期的で、バックアップを気にせずとも「クラウドにログインすれば同じ環境」という、今では当たり前の世界観に徐々に移行していったのだ。

Outro

それでも、TOTP は最終的に文字列を入力する。Autofill に頼るにしても、本来は文字列にしたくはない。2FA はできれば WebAuthn が望ましい。

「WebAuthn も共有できればな」というのが、うっすらみんなの本音としてあるが、タブーなので決して口には出せない、そんな状態だったように思う。

Apple が口火を切るまでは。