自分のパスワードやMFA(多要素認証)の管理方法についてまとめた記事です。

パスワード管理とTOTP(Time-based One-time Password)の管理として1Passwordを使い、MFA(多要素認証)の2要素目としてYubiKeyを2枚使っています。

パスワード管理とMFA管理を安全で使いやすくするのはかなり複雑で難しいため、完璧にやるのが難しいです。 そのため、その難しさから二要素認証を設定するべきアカウントも手間などから設定を省いてしまったり、管理方法に一貫性がありませんでした。

この記事では、パスワード管理/MFA管理の戦略を決めることで、どのサイトのどのアカウントのパスワード管理をあまり頭を使わなくてもできるようにするのが目的です。利便性と安全性のバランスを意識はしていますが、この記事のやり方が正解ではないので、各自の目的に合わせて読み替えると良いと思います。

用語

  • MFA: 多要素認証のこと
    • 2要素認証といった場合は2つの要素で認証(ログイン)する
    • 1つ目の要素はほとんどの場合はパスワード(知識認証と呼ばれる)なので、大体2つ目の要素のこと
    • もう少し抽象的にいう場合は複数の要素で認証するので、MFAという
    • TOTP、Face ID(生体認証)、セキュリティキーなどは、多要素認証を構成する要素の1種
    • 重要なものが置いてある家にパスワードだけで入られても困る(パスワードは漏洩することがあるため)ので、もう一つ物理的な鍵(セキュリティキー)を組み合わせて入れるようにするというのが、多要素認証をするという話
  • TOTP: 2要素認証でメジャーなワンタイムパスワードを生成する仕組みのこと
    • Google Authenticator、Microsoft Authenticator、AuthyなどでQRコード読んで登録すると、ワンタイムパスワードを生成できる
    • 1Password、Appleのキーチェーンのようにパスワード管理アプリ自体がサポートしてることもある
  • セキュリティキー: Yubikeyなどの物理的なデバイスのこと
    • FIDOという規格がありそれをサポートしているデバイス
    • YubiKeyTitan Security Keyなどがある
    • ウェブブラウザとウェブサイトがこの仕組みに対応してると、2要素認証などにセキュリティキーが使えるという仕組みがFIDO認証と呼ばれる

パスワード管理方法のNotionテンプレート

この記事で書いている管理方法をまとめたNotionテンプレートを公開しています。

右上の複製ボタンから、Notionにコピーして利用できます。

テンプレートでは、アカウントが重要アカウントかサイトがセキュリティキーに対応しているかなどにチェックを入れると、自動的に管理方法を出してくれます。

Template

テンプレートを見れば大体やりたいことはわかると思いますが、どのような流れになっているかを解説していきます。

必要なもの

このパスワード管理/MFA管理をするには、次の2つのものが必要です。

  • 1PasswordBitwardenのようなTOTPに対応したパスワードマネジャー
  • Yubikey などのセキュリティキー を 2枚
    • セキュリティーキーを2枚使うのは、紛失対策で片方はバックアップ用途です
    • iOSやAndroidなどのモバイル端末で使う場合は、NFCに対応したものが便利です(Yubikey NFC)

自分の場合は、1PasswordYubiKey 5C NanoYubiKey 5C NFCを利用しています。 YubiKey 5C NanoがMacbook Proに挿しっぱなしのメインとなるセキュリティキーで、YubiKey 5C NFCはバックアップ用のスペアキーです。 モバイルでセキュリティキーが定常的に必要となるアカウントがほとんどなかったので、Nanoをメインにしています。

YubiKey 5C NFCは、Cloudflare経由だと1本$10程度で販売してくれていたキャンペーンを利用して購入しました。

また、1Passwordはオープンソースソフトウェア開発者などが無料で利用できる1Password for Open Source Projectsを申請して利用しています。

アカウントごとの管理方法を分ける

アカウントごとにどの方法でMFAを管理するかを分けています。

YubikeyのようなセキュリティキーでMFAを管理すると、WebAuthN APIはキーが登録済みのOriginでしか動かないので、MFA Fatigue攻撃2FAリレー攻撃(フィッシング)などを防げて安全です。

実際にSMS、TOTP、アプリの2段階認証を行っていても、フィッシングサイトで入力したOne-time tokenをそのまま正規のサイトにリレーしながら不正ログインする2FAリレー攻撃などが行われています。

一方で、同じ攻撃がCloudflare社に対しても行われていましたが、Cloudflare社員はセキュリティキーを利用していたため、突破されなかったことも報告されています。

全てのサイトのアカウントにセキュリティキーを使えばかなり安全ですが、実際にはそういう運用は難しいです。 サイト自体がセキュリティキーに対応してなかったり、セキュリティキーのみをMFAにできないサイトがあったり、利便性からセキュリティキーを使うのが難しいサイトもあります。(また、個人だとSSOでログインしてないサイトも多いので、セキュリティキーでカバーできるサイトはより少なくなる)

また、全てのアカウントがセキュリティキーで守るほど重要なアカウントではないという点もあります。 仮にパスワードが漏れて不正アクセスされてそこまで影響が大きくないなら、TOTPやSMSのMFAで必要十分ともいえます。

MFAとしてTOTPやSMSに対応しているサイトは多いですが、セキュリティキーはまだそこまでではありません。 まだ、セキュリティキーはツールやサイトの対応が少なかったり、モバイルでの体験が良くないなどの利便性で劣る部分があったりします。

まずは最初にやることは、MFAが設定できるサイトはMFAを設定することです。 しかし、MFAとしてSMS/TOTP/セキュリティキーなどの選択肢があり、どの方法で管理すればいいのか迷ってしまって結局設定しないという問題がこの記事の出発点です。

自分の場合は次のようなフローチャートで管理方法を決めています。

MFAの保存先のフローチャート

次のフローチャートは、MFAが設定できる場合に1Password または Yubikey のどちらで扱うかを決めています。

MFA Flowchart

まず、重要なアカウント or 重要ではないアカウントで分岐します。 重要の定義は人それぞれですが、たとえば色々な個人情報が入っていたり、お金の入出力が制限なくできたり、乗っ取ることで影響範囲が広い行動(npmパッケージにマルウェアを仕込むなど)ができる場合は、重要なアカウントだと思います。 一方で、重要ではないアカウントは管理コストよりも利便性や簡単さを優先した方がいいので、1PasswordにTOTPを保存することでMFAを管理します。

次の分岐は、重要なアカウントで、そのサイトがセキュリティキーをサポートしてるかどうかで分岐します。 そもそも、サイトがセキュリティキーをサポートしてないなら、Yubikeyをセキュリティキーとして使うことはできません。 その場合は、今後サイトがサポートしてくれるまでは、1PasswordにTOTPを保存することでMFAを管理します。 次のページには、サイトがセキュリティキーに対応してるかがまとめられています。

最後の分岐は、サイトがセキュリティキーをサポートしていても、セキュリティキーのみで運用できるかの分岐です。 これは、サイト側の実装でMFAとしてセキュリティキーのみできないパターン(1PasswordやGitHub)、セキュリティキーが1つしか登録できないパターン(PayPal)、利便性の都合からセキュリティキーのみにするのが難しいパターンなどがあります。

セキュリティキーのみをMFAとして登録できると、TOTPやSMSを使った2FAリレー攻撃がそもそもできなくなるので一番安全です。 一方で、セキュリティキーで認証しないと行けなくなるので、モバイルで困るケースはないかや運用的にできるかどうかが判断基準になります。

セキュリティキーのみで大丈夫となったら、そのサイトには用意しておいたメインとバックアップのセキュリティキーを2つ登録します。 セキュリティキーを2つ登録することで、片方を紛失しても、ログインして無くした方を消したり、さらにスペアを追加できます。

自分の場合は、一部の例外を除いてこのフローで管理方法を決めています。 その例外となるのは、1Password自体のMFAです。

1Password自体のMFAはセキュリティキーのみにはできないため、Authenticator App(TOTPのこと)が必須になっています。

1Passwordは、他のサイトのパスワードやTOTPも管理しているため、漏れた場合の影響が明らかに大きいです。 そのため、1Password自体はTOTPをなしにして、セキュリティキーのみで扱いたいサイトです。

実はYubikey自体もYubico Authenticatorと組み合わせるとTOTPを扱えます。 Yubikeyを刺した状態でYubico Authenticatorを立ち上げると、Yubikeyに保存した情報を元にTOTPのOne-Time Passwordを生成できる仕組みです。 そのため、1Password自体のMFAは、1つはYubikeyのセキュリティキーを登録し、もう一つのYubikeyにTOTPを保存しています。

フローチャートにすると次のようになります。

MFA Actual Flow

1Passwordで、MFAが必要となるは新規ログインぐらいで、頻度は多くないので特別対応をしています。 (Yubikey1枚につきTOTPを保存できるのが32コと多くなかったり、コードのバックアップはハード的にできないので、あまり数を増やしたくない方法です)

このフローチャートで大まかに次のどちらでMFAを管理するかを決めています。

  • 1PasswordのTOTP
  • Yubikey 2枚

📝補足: 1PasswordとTOTP

1PasswordにTOTPも保存するのは、2要素認証ではなく、2段階認証と言えます。

そのため、この管理方法は次のように言い換えられます。

  • 重要ではないアカウント: 1Passwordを使って2段階認証
  • 重要なアカウント: Yubikeyを使って2要素認証

TOTPに1Password以外を使って、パスワードとTOTPのコードを別の場所に保存する方法もあります。 この場合、TOTPを扱うAuthenticator Appsが、サイトのOriginとTOTPを紐付けて管理できないと、2FAリレー攻撃などのフィッシングに対応できません。 (1Passwordの場合は、パスワードと同じサイトのURLに紐づいているはずです)

サイトのOriginとOne-Time Passwordの紐付けの問題は、SMSでOne-Time Passwordを受け取り自動入力する<input autocomplete="one-time-code" />でも発生します。

このSMSのOne-Time PasswordとOriginを紐付けるWeb OTP APIもありますが、対応してないサイトは多いです。

また、Authyを使う場合は、Authy自体の2要素認証としてYubikeyを使えない問題もあります。 他の方法として、Yubikey自体にTOTPを保存して、YubikeyをTOTPとして扱うフローも考えましたが、管理が複雑になって最初の問題が解決できないので避けました。

2FAリレー攻撃などは実際には難しい(パスワード自体はOriginに紐づくパスワードマネージャーで入れるため)ので、TOTPを分けるフローにしなかったのは、どちらかというと管理の複雑性を減らすのが主な目的です。

MFAのバックアップコード

多くのサイトはMFAを登録するとバックアップコードを発行しています。 このバックアップコードの呼び方はリカバリコードなど色々ありますが、基本的にはMFAとして登録してるものが使えない時に使える予備のコードです。 発行しないという選択肢もありますが、発行した場合は先ほどのフローチャートと同じように決めています。

Backup Code Flow

フローチャートにしましたが、シンプルに書けば次のようになります。

  • 1PasswordにTOTPを保存してる場合は、1Passwordにバックアップコードを保存
  • Yubikeyのみで管理してる場合、バックアップコードを印刷、オフラインのHDDやSDカードに保存

基本的にMFAの管理方法に合わせて、バックアップコードを保存するという感じにしています。

TOTPとバックアップコードを同じ1Passwordに保存する意味ですが、仮に1Passwordのアカウントが侵害された場合にTOTPが見れれば、バックアップコードが漏れることで影響がより大きくなることはほとんどありません(アカウントが乗っ取られるという結果は同じ)。 また、サイト側の問題でTOTPではアクセスできなくても、バックアップコードでアクセスできるような救済処置がされるケースがあります。 これはサイト側の実装を知らないとどうにもならないので、利用者が意識して管理方法を分けることをとても難しくさせます。

そのため、1PasswordにTOTPを保存してる場合は、1Passwordにバックアップコードを保存という単純化をしています。

Yubikeyで管理している場合は、バックアップコードをオンラインに載せてしまうとYubikeyの意味がなくなってしまうので、オフラインで管理するという形にしています。同じ場所(家)に保存してると火災などでセキュリティキーと一緒になくなる可能性があるので、マルチリージョン的に別の場所になってた方が安全ですが、安価で手軽な方法が思いつきませんでした。

MFAの管理テーブル

ここまで、管理方法を色々書いてきましたが、実際のサイトで見た方がわかりやすいと思います。

次のNotionテンプレートのテーブルに、アカウントを追加してそのアカウントに対する次の項目にチェックを入れれば、 ここまで書いたフローチャートの結果を自動的に出してくれます。

  • 重要アカウント: 個人にとって重要なものかどうか
    • お金に関わるアカウントか、個人情報が含まれているか、他者への影響があるかなどで判断
  • セキュリティキー対応: セキュリティキーに対応したサイトかどうか
  • キーを必須にできる?: セキュリティキーのみをMFAとして利用できるサイトかどう
    • SMSやアプリなどをMFAとして利用するのを無効化できるか
    • セキュリティキーのみをMFA(WebAuthN)として利用すると、キーを登録済みのoriginでしか動かないのでMFA Fatigue攻撃や2FAリレー攻撃(フィッシング)などを防げる

Template

いくつか実際にサイトを見てみます。 この”重要アカウント“や”キーを必須にできるか“は個人の指標なので、各自で判断してみてください。

1Passwordは先ほども出した例外なので、MFAは”Yubikey1を登録 + Yubikey2にTOTPを保存“して、バックアップコードはオフラインに保存します。 GitHubは自分の中では特殊で、漏れた場合の影響範囲が広いので、1Passwordと同じく例外として扱っています。

Googleアカウントは、セキュリティキーのみで運用できるサイトなので、MFAは”Yubikey2枚で管理“して、バックアップコードはオフラインに保存します。 さらにセキュアな高度な保護機能プログラムというものもあります。

npmは、セキュリティキーのみで運用できるサイトですが、--auth-type=webの体験があまり良くなかったり、lernaがセキュリティキーに対応してなかったりなど利便性の部分でちょっと問題がありました。 そのため、まだキーを必須にするのが難しかったので、MFAとバックアップコードは”1Passwordに保存“して管理しています。

1Passwordなら、opコマンドで、TOTPのトークンをコマンドラインから取得できます。 そのため、npm publishする際にMFAが必須になる”✅ Require two-factor authentication for write actions”を有効化していても、npm publish --otp $(op item get --otp npm)のように書けば、MFAありなしの体験はほぼ変わりません。

Amazon.co.jpは、セキュリティキーに対応していません。 そのため、”1Passwordで管理 or その他対応“となり、TOTPとSMSのMFA管理になっています。

重要なアカウントではないサイトは、単純に1Passwordで管理します。 このテーブルにわざわざ入れる必要がないので、実際はテーブルには追加してません。

結果

このパスワード/MFA管理方法で整理を実際にやってみて、迷いなくMFAを設定できるようになった気がします。 今まで、管理方法が色々ありすぎて迷って放置してる部分があったので、やり方がある程度決まってると気持ち的に楽な気がします。 (単純にMFA設定できてなかったやつ = 重要ではないアカウントに、1PasswordでTOTPを気楽に設定できるようになったのが大きいかも)

今までTOTPにAuthyを使ってる部分がありましたが、全て移行してAuthyを使わないで済むようになりました(TOTPを再発行して1Passwordにしたり、Yubikeyに移行したので消したりした)。

また、一部のバックアップコードがDropboxに眠っていたので、バックアップコードを再発行してそれぞれの管理場所に移しました。

長く書いてるので複雑な感じに見える気もしますが、結果的には1Password or Yubikeyの2択なのでシンプルになった感じです。 そして、本当に”重要なアカウント”はおそらく全アカウントの1-2%以下とかだと思うので、大部分は1Passwordに保存という形になって、重要なものだけを意識して管理というイメージで動けます。

1Passwordはソフトウェア的な良さがあり、Yubikeyはハード的な良さがあるので、それぞれをいい感じに組み合わせ行けるのが良いと思いました。