パスワード運用のベストプラクティス

## パスワードの生成方法

パスワードを強くする観点では何よりもランダムさが重要です。

### 乱数生成器を使う

ランダムなパスワードを作るには、乱数生成器を使うのが最適です。

あなたがソフトウェア技術者ならば、ターミナルに `openssl rand -base64 9` と入力するだけですぐにパスワードとして適したランダムな文字列が手に入ります。[^1]

[^1]: OpenSSL がインストールされていない場合、多くの環境では `LC_ALL=C head -c 9 /dev/urandom | base64` で代用できます。

#### パスワード管理ツールを使う

パスワードを管理するための専用ツールに内蔵されたパスワード生成機能に頼るのも良いやり方です。最近では Chrome 等の有名ウェブブラウザーはパスワードを生成・保存する機能を内包しているので、専用ツールを別途インストールせずとも手軽にパスワードを生成でき (さらにそれを自動的に保存してくれ) ます。

### パスワードの強さをチェックする

パスワードの強さに確信を持ちたい場合は、ツールを使ってチェックするのも良いでしょう。

パスワードの強さを確認するツールはいくつかありますが、個人的には [zxcvbn](https://github.com/dropbox/zxcvbn) をお勧めします。辞書に載っている単語や連番の使用等、パスワードを弱くするパターンはいろいろありますが、zxcvbn はそれらのパターンの多くに対応しています。単に文字数や種類だけで強さを判定するツールでは、これらのパターンを含む弱いパスワードを見逃す可能性があります。

単にすぐパスワードの強さを確認したいだけなら、[このテストページ](https://lowe.github.io/tryzxcvbn/)を開けばブラウザー上で確認できます。スコアが 4/4 になるのがベストであり、スコアが低いほど危険です。

### アンチパターン: パスワードの手動での考案

人間の脳内でパスワードを考案しようとする行為は、何らかの規則的なパターンを含む弱いパスワードを生成する可能性が高まるため、お勧めできません。 `7epK20Cm/3` の様な一見ランダムに見える文字列であっても、それを人間の脳で生成した場合、その人の個人的な癖が反映されて片寄ったパスワードになっている可能性があります。[^2]

> あの人、ジャンケンするとき大体いつもパーを出すよね。本人は気付いてないみたいだけど

[^2]: パスワードが十分に長ければこの様な癖の影響はカバーできるという見方もあります。とはいえ癖の影響がどれほどのものなのかを定量的に見定めることは難しく、パスワードをどれだけ長くすれば安全なのかが不透明です。それよりも素直に乱数生成器を使うことをお勧めします。

#### アンチパターン: 規則的な文字の置き換え

文字列に含まれる `1` と `I` と `l` を置き換えるみたいなやり方は、パターンの数が限られているため、パスワードを強くする効果はあまりありません。

そもそも、このような置き換えをしたくなるのは、置き換え前の文字列が辞書に載っている単純な単語なのでそのままパスワードとするには忍びないという動機に基づくものであることが多いと考えられますが、そもそも辞書に載っている単語を元にパスワードを作ろうとすることをやめるべきです。

なお、前述の zxcvbn はこのような置き換えの多くのパターンを見抜いてスコアを減点します。

#### アンチパターン: サービス名にちなんだ文字の付加

サービスごとにサービス名にちなんだ文字列をパスワードの先頭や末尾に付加することで、パスワードの使い回しを避けつつパスワードを暗記しやすくするという方策を取る人もいます。[^3] 例えば `nibQgnrN` を共通部分として決めておいて、Twitter のパスワードは `nibQgnrNtwttr` で YouTube のパスワードは `nibQgnrNytb` で Microsoft のパスワードは `nibQgnrNmcrsft` などという風にパスワードを決めます。

このやり方は一見良さそうに見えますが、一度パスワードがどこかのサービスで破られてしまうと、パターンを見抜かれて他のサービスのパスワードも推測されてしまう危険性が比較的高いと考えられます。上の例では、`nibQgnrNtwttr` の `twttr` の部分がサービス名の Twitter にちなんだものであることは比較的容易に推察できます。

[^3]: 筆者も以前はこの方式でパスワードを管理していました。

## パスワードのポリシー

### パスワードの長さ

望ましいパスワードの長さは、用途によって異なります。

ウェブサイトにログインするためのパスワードの場合、入力されたパスワードが合っているかどうかの判定がウェブサイトのサーバー側で行われるので、サーバーの性能や仕様が試行回数のボトルネックになります。普通のサーバーではログインが何度も試行されたらアクセス制限をかけるでしょうし、もしアクセス制限がかからない場合でも攻撃者はせいぜい毎秒数千通り程度の個数しか試行できません。大文字・小文字・数字 (合計 62 種類の文字) を使ってパスワードを作成して百年以内に解読される確率を一億分の一としたいとすると、一秒間に一万回試行されると仮定して

``` math
\log_{62}(10000 \times 60 \times 60 \times 24 \times 365.25 \times 100 \times 100000000) \approx 12
```

となり、12 文字あれば十分そうだといえます。

一方で、ファイルを暗号化するためのパスワードの場合、パスワードが合っているかどうかは攻撃者自身が判定できるので、攻撃者が多くの計算資源を用意すればするほど解読が容易になります。大金をクラウドコンピューティングに注ぎ込めば毎秒で何億通りもののパスワードを試すこともできるでしょう。将来的にコンピューターの計算能力が向上してゆくことを考えると、パスワードはその分を見越して長くしておく必要があります。現時点での試行頻度が毎秒一兆通りで、計算能力が二年で二倍になるとすると、

``` math
\log_{62}(1000000000000 \times 2^{100/5} \times 60 \times 60 \times 24 \times 365.25 \times 100 \times 100000000) \approx 24.9
```

となり、25 文字は必要ということになります。

### パスワードに含まれる文字種の多様性

「英字と数字と記号を組み合わせなければならない」というような、パスワードに使われる文字の種類の多様性を強制する規則を設けることはあまり良い考えではありません。文字の種類の組み合わせに関するルールがある場合、パスワードを当てようとする攻撃者の観点から見ると、種類が組み合わさっていないパスワードは不正解であるということが最初から分かってしまうので、その分 的を絞った攻撃が可能になります。攻撃者に余計な情報を与えないようにするために、パスワードの作り方に関する制約はできるだけ設けない方が好ましいといえるでしょう。

実際にパスワードに使われている文字が多様な種類の文字を含んでいるかどうかは、(パスワードが適切な乱数から生成されている限りは) あまり重要ではありません。記号を含む半角文字は 95 種類あり、記号を除いた半角文字 (62 種類) に比べると一文字当たりの情報量が $\log_{62}95$ つまり約 1.1 倍多くなりますが、逆に言えばパスワードの文字数を 1.1 倍にすれば記号を含まないパスワードでも記号を含むパスワードと同程度の情報量を持つことになります。文字の多様性に気を揉むくらいならとっととパスワードを数文字長くした方が簡単です。どうせパスワード管理ツールに記憶させるのだからパスワードの長さは問題になりません。

### パスワードの定期的な変更

理論上はパスワードを頻繁に変更した方がパスワードを当てられる確率が下がりますが、パスワードが十分に長ければその差は無視できる誤差でしかありません。パスワードを何度も変更する手間に見合わないので、パスワードを定期的に変更するのはやめましょう。

### パスワードの使い回し

パスワードの使い回しは危険です。複数のウェブサイトやサービスで同じパスワードを使っていると、万一どれかのサイトやサービスで情報が漏洩したりパスワードが破られたりした場合に、自分の使っている他のサイト等もすぐに乗っ取られてしまう危険性が高まります。必ずサイト毎に別々のパスワードを用意するようにしましょう。そして、それらたくさんのパスワードを暗記することは難しいので、上述のようにパスワード管理ツールにパスワードを記憶させましょう。

## パスワードの保存方法

パスワードはパスワード管理ツールに保存するのがベストです。ただし絶対にそうしなければならないわけでもありません。

### パスワード管理ツールを使う

パスワードの保存方法としては、パスワード管理ツールにパスワードを保存するのが最も確実で安全と考えられます。今どきの一般的なパソコンやスマートフォンでは OS やウェブブラウザーにパスワードを保存する機能が付いているので、それを使うのが便利でしょう。あるいは、複数の OS やウェブブラウザーを日常的に使っている人の場合は、それらに横断的に対応した専用のパスワード管理ツールを使うのも良いでしょう。

#### パスワード管理ツールに保存すべきでないパスワード

ただし、パスワード管理ツールで管理するのに適さないパスワードがいくつかあります。

一つ目は、パスワード管理ツールをロック・アンロックするためのマスターパスワードです。パスワード管理ツールを使うためのパスワードをパスワード管理ツール自身に管理させることは無意味ですね。

もう一つは、クレジットカードの暗証番号や、スマートフォン等の画面ロックを解除するための認証コードです。この類のコードは本人が暗記して必要な時に本人が直接入力するという前提でシステムが設計されています。パスワード管理ツールに保存しても入力時に自動的に補完させることができないので不便なだけです。

### パスワードをテキストファイルに保存する

パスワードをテキストファイルに保存するのは、利便性の観点ではパスワード管理ツールに劣るものの、悪い方法とも言えません。筆者はパスワード管理ツールのバックアップとして別途テキストファイルにパスワードを記録しています。

可能ならば、パスワードを保存しているファイルは暗号化しておくのが良いでしょう。筆者は Vim の暗号化機能を使ってテキストファイルを暗号化しています。あるいは、プレーンテキストではなく Word や Excel の様な暗号化に対応したファイル形式を使う手もあります。最近は Windows の BitLocker や macOS の FileVault 等 OS がファイルシステムレベルで暗号化機能を提供しているのでそれに頼るのでも良いでしょう。

### パスワードを紙に書く

パスワードを紙に書いて保管するのは危険だという人もいますが、それは場合によりけりです。基本的には、パスワードを書いた紙を失くしたり盗まれたりしない限りは、安全だといえるでしょう。あなたが日常的に家の鍵やクレジットカードを失くすようなおっちょこちょいな人でなければ、パスワードを紙に書いておくことのリスクはさほど高くないと考えられます。

ただし、紙を家族に見られるリスクがあることや、コピー & ペーストができないので入力が面倒であることなどのデメリットはあります。

### アンチパターン: パスワードを暗記する

パスワードを暗記しようとするのは、もっとも良くないやり方です。

正確には、パスワードを暗記しようとすること自体が悪いわけではありません。ただ、暗記しようとすると、パスワードを覚えやすいようにパターン化したり使い回したりして、隙が生まれやすくなります。

パスワードの使い回しは良くないという話を既に述べましたが、サービスごとに異なるパスワードを登録すると、(あなたがよほど超人的な記憶能力を持っていない限り) パスワードを暗記するのは困難です。よって、パスワードを暗記しようとするのは諦めましょう。上述のように、パスワード管理ツールを使うべきです。ただし、パスワード管理ツールに保存すべきでないパスワードに関しては例外的に暗記することになるでしょう。