Webサイトにはパスワードの登録に余計な制限をかけているサイトが少なからずあります。特に最悪なのはたった20文字程度のパスワードしか許可しないサイトです。
Webサイトのパスワードは基本的には覚える必要がありません。安全性を第一に考えると十分過ぎるくらいの長さのランダムパスワードを設定する/設定できるようにすると良いです。
TL;DR;
パスワード用のランダム文字列が必要でアクセスした方は以下のURLを参照してください。生成されたランダム文字列の一部、90文字くらい、をパスワードとして使うと安全です。
パスワード用のランダム文字列生成ページ (ランダム文字列を表示します)
今の時代、パスワードを覚えておく方がナンセンス
OnePasswordなどのパスワードマネージャーを使っている方はそれを使いましょう。今のパスワードマネージャーは十分に安全になった、と思います。1
ChromeでもFirefoxでも、パスワードを記憶させることができます。もちろん「記憶させることにリスク」はあります。しかし、単純なパスワードを設定したり、使いまわしたりする方が余程危険です。
- 覚える必要がないパスワードはCSPRNGで生成された、十分に長いランダムな文字列にする(90文字以上など)
長ければ長いほど、総当たり攻撃に強くなります。本当にランダムな文字列なら90文字あれば十分以上です。
あるべきパスワード仕様
- 少なくともBASE64エンコードで使うASCII文字は許可する(英数字、+、/、=)
- 長さ制限は12文字以上、少なくとも120文字以上を上限にする(入力バリデーションで1000文字程度まで、ロジックバリデーションで500文字程度までは許可する)
- UIに”最大文字数の制限”を書くくらいなら「12文字以上、他のサイトと同じパスワードは使わない」と説明する
- 強いパスワードを要求する場合、文字列を分析するJavaScriptライブラリを利用する。例えば、コレなど
- その上でパスワードのコピー&ペーストを許可する(本当に強いパスワードはCSPRNGで生成したパスワード!)
CSPRNGを使った安全なパスワード生成方法
Linuxを使っているならopensslコマンドが入っているハズです。2
openssl rand -base64 69
これで十分に長いランダム文字列で、これ以上にない最強のパスワードが生成できます。
安全なランダムパスワード文字列を生成するWebアプリを使うのも1つの手法です。opensslコマンドが使えない方などはこれらを使うのも仕方ないでしょう。
少しでもおかしな(脆弱な短いパスワードし許可しない)仕様のパスワードを要求するサイトが減る様に作りました。上記のサイト(私のサイト)から使っても構いませんが、できれば自分のWebサーバー(インターネットからアクセスするならHTTPS必須)にインストールして使ってください。
パスワードをコピー&ペーストするリスク
パスワードをコピー&ペーストすることはリスクフリーではありません。コピーした情報は少なくとも1つ、履歴機能を持つクリップボードなら10や20は保存してしまいます。
仮想マシンやリモートデスクトップはホストマシンから分離されていますが、多くの設定で「クリップボード共有」を行っています。コピーしたパスワードは仮想マシン/リモートデスクトップからも参照可能です。
こういったリスクがある上で仮想マシンやリモートデスクトップは使いましょう。
また、クリップボードは他のインストール済みアプリからも参照可能です。余計なアプリケーションは入れない、を守りましょう。
Googleアカウントなどの2要素認証は必須
パスワードを覚えさせなくても、Webアカント登録にgmailアドレスやgmailで読めるメールアドレスを使用する場合、メールアドレスのアカウントに侵入さえすれば、後は芋づる式に他のWebアカウントに侵入できてしまいます。
このため、本当はパスワードを覚えさせる/させないに関係なく「メールアドレスのアカウント」は厳重に保護する必要があります。
ブラウザにパスワードを覚えさせた場合、攻撃が簡単になるだけです。ここで増えるリスクは許容可能でしょう。3
とにかく「メールアドレスのアカウント」、例えばgmail(Google)アカウント、は2要素認証でしっかり保護し、2要素認証アプリ(Google認証など)をインストールしたスマホのロック機能も確実に使うようにしましょう。余計なアプリは極力入れない、も重要です。
BASE64の非英数文字
BASE64エンコーディングには +、/ が含まれます。( = はパディング)これらの非英数字文字を使わなく(削除)しても十分に強いパスワードになります。しかし、こういった削除は僅かですがエントロピーを減らす働きをします。
今でも認証の要と言えるパスワードを少しでも弱くするような仕様にはしない方が良いでしょう。Webサイト開発者の方には最低限でもBASE64エンコーディング文字だけはサポートするようになパスワード仕様をお願いします。
論理的に最強のパスワード
論理的に最強のパスワードを考えてみます。それは
- パスワードはパスワードハッシュ関数がサポートするビット幅と同じエントロピーを持つ真にランダムな値が最適
となります。
ユーザーからはハッシュアルゴリズムが何なのか分らないので取り敢えず、ビット幅の大きなハッシュ関数が利用されている、512ビット程度、だと仮定します。
ハッシュ関数の入力としては512ビット程度のエントロピーを持つパスワードにすると最強かつ最適(最も小さい)のパスワードになります。
512ビットのバイナリ値は64バイトです。効率良くバイナリ/テキスト変換ができるBASE64だと+33.33%の文字数が必要になります。バイナリ⇒テキスト変換したBASE64だと86バイト(86文字)必要です。4
CSPRNG(暗号学的疑似ランダム生成器)は出来るだけ癖がない、ランダム値を生成するように設計されています。しかし多少の癖があると仮定して少し多目の方が真のランダム値になるとすると
- BASE64の86文字+αが必要
となります。従って
- 概ね90文字くらいのランダムパスワード
にすると最強のパスワードになると考えられます。
パスワードは強ければ強い程良いのですが、ハッシュ関数の性能(仕様)を越えるランダム値を設定しても意味がありません。このケースの場合、90文字程度の文字列が論理的に最強のパスワードになります。
覚えなくて良いパスワード、にはランダム文字列の90文字くらいのパスワードを設定しましょう!自分で覚えない&入力しないパスワードに最強のパスワードを使わない良い理由はありません!
Webサイト開発者の方には最低限でも最大120文字程度はサポートするパスワード仕様をお願いします!
最強のパスワードを使うメリット
わざわざそこまで強いパスワードを設定しなくても。。。と思った方もいるでしょう。とっておきのメリットを紹介します。
Webアプリユーザーには、パスワードがどの程度安全に保存されているのか、判りません。パスワードをデータベース等に保存する場合、基本的にはcrypt関数(今ならpassword_hash関数)やPBKDF2関数などの「パスワード専用のハッシュ関数を適切に用いて」保存する必要があります。しかし、世の中には脆弱なパスワードの保存方法が沢山利用されています。
例:crypt関数の使い方が間違っている
$crypt_pass = crypt($user_pass);
例:ハッシュ関数だけ使っている
$crypt_pass = hash(‘sha256’, $user_pass);
これらは非常に悪い実装ですが、歴史的経緯などもあって今でもこうなっているWebサイトもあるでしょう。パスワードが8文字から12文字の金融系サイトまである始末です。更にもっと酷い、平文保存さえもあるのですから、無いと考えるのは無理です。
どうしようもないcrypt関数利用方法や平文保存は保護できませんが、最強のパスワードを使っていれば、
$crypt_pass = hash(‘sha256’, $user_pass);
や
$crypt_pass = hash_pbkdf2(‘sha256’, $user_pass, ‘weak salt’, 1);
といったダメな実装で$crypt_passの情報漏洩があっても、最強のパスワードならパスワードの安全性は確実に保証されます。
詳しい説明は省略しますが、これが暗号学的ハッシュ関数の特徴です。
また、hash_pbkdf2(), password_hash()といった”パスワードハッシュ化専用のハッシュ関数を正しく利用”しても短いパスワードや弱いパスワードは保護できません。
自分のアカウントの安全性を可能な限り最大化したい!そういった場合は最強のパスワードを使う方と多くのケースでアカウント流出のリスクを回避できます。
最後に、このエントリは自分専用のデバイスでのみ、自分のアカウントにログインすることを想定しています。基本的に他人のデバイスや共有デバイスでWebアカウントにログインするのはやめましょう。
-
- 私は3rdパーティーのパスワードマネージャーが信用できなかったので今も使っていません。Chrome(Google)のパスワードマネージャーを使っています。リスク分散もお勧めなので、信頼できる3rdパーティーのパスワードマネージャーを使うのも良いと思います。その際に、ユーザーと紐づけるメールアドレスはGmailと無関係の物にしないとリスク分散の意味が薄れます。 ↩
-
- 本当に安全なパスワードはTrue RNGから生成したパスワードですが、一般にはCSPRNGでも十分なランダム性をもつ安全な乱数だと考えられています。 ↩
-
- 実は一番お勧めはアカウント登録するメールアカウント(パスワードリセットが出来るメール)は別にして普段は使わない、です。 ↩
- パスワードの強さは「使っている文字種」で決るのではなく、パスワードが持っているエントロピー(≒ 情報量)で決まります。なので真のバイナリランダム値をエンコーディングしてASCII文字に変換しても、情報が失わなれなければ強いパスワードが生成できます。「パスワードに記号を多用する」は短いパスワードの情報量が少ないことを補う為のプラクティスです。十分な長さのランダムパスワードなら記号を多用する必要はありません。 ↩