パスワード管理ってみんなどうしてるの？？こうするといいと思うよ！

#パスワードめんどくさい…

いろんなサービスに登録するたびに作ることになる「パスワード」という奴ですが

これ、管理が非常に厄介ですね。

「同じパスワードを使うな」と言われても、


たくさんのパスワードを全部覚えていられるわけがないですね。

ちなみに、数年前まで「パスワードは定期的に変更しろ」と言われていたのですが、ここ数年は、**パスワードの定期変更は悪手**ということで決着がついたようです。(執筆日2019年12月9日)

企業のセキュリティ体制を審査するPマークの発行機関も、パスワードの定期変更を求めなくなりました。

参考
http://www.pmarknews.info/privacy_mark/52072685.html

とはいえ、たくさんのパスワードを管理しなきゃいけない状況は変わってません。

この記事では、いくつか方法を挙げて、比較してみたいと思います。

現実的に使えそうな気がするものには、見出しに「現実的か」と付けておきました。

「現実的だ」や「理想である」などと断言していないのは、理想の管理方法がどうやら無さそうだからです。残念。

#前提

ブラウザや端末に標準でついている「パスワード保存機能」は使う前提とします。

なので、「サービスを利用するたびにパスワードを入力する必要がある」**というわけではない**です。

ではどんな場面でパスワード入力が必要になるかというと

 - 新しいスマホやPCを導入した時
 - 普段と違う端末からサービスを利用する時
 - あるサービスを久しぶりに使うため、パスワード入力を求められた時
 - セキュリティの観点から定期的にパスワード入力を求められる時

などだと思います。

毎日入力しなくていいせいで、逆に忘れがちなんですよね。パスワード。

なので、忘れないために、結局、パスワード管理方法が必要になります。

パスワード記憶機能は万能じゃない。

### ブラウザやサービスの提供者は信用しているものとする

ところで、この前提の話で大切なことは

**ブラウザや端末の提供者は信用しているものとする**

ということです。

パスワードを覚えさせたブラウザや端末が、裏で勝手にパスワードを収集していたら、利用者からしたら知りようがないわけです。

でも、「そういうことはしていないだろう」と、ブラウザや端末の提供者を**信用**して、普段我々はパスワード記憶機能を使ってるわけです。はい。


では、パスワード管理方法の検討に入っていきます。


#覚えやすい文字列

「password」とか「admin」とか「自分の誕生日」とか「好きな単語」とか「IDと同じ」とか。そういう奴です。

「辞書攻撃」という奴で速攻で破られます。

攻撃者は「人間がパスワードに設定しがちな文字列のリスト(辞書と呼ばれます)」を持ってますので、それを片っ端から調べられておしまいです。

###メリット

 - 覚えやすい

###デメリット

 - 破られやすい

#p@ssw0rd1 みたいな奴

「password」を部分的に記号や数字で置き換えたものです。10年くらい前に流行ったやり方かな。

これも「人間がパスワードに設定しがちな文字列のリスト」に入っておりますので、速攻で破られます。

セキュリティの専門家でもない我々が思いつくような範囲の「変換規則」なんて攻撃者は全て把握していることでしょう。


###メリット

 - 覚えやすい

###デメリット

 - 破られやすい

#ぐちゃぐちゃな文字列をがんばって覚えて、全サービスに使う

これなら破られにくいですが、

一つ破られたら他も全部破られるという非常にまずい欠点があります。

「一つ破られたら」の実現可能性についてですが

例えば

 - 偽サイトに騙されて入力してしまう
 - 入力の様子を後ろから見られる・カメラで撮られる
 - 暗号化されていない通信でパスワードを送ってしまい、それを傍受される
 - サービスの側の管理が甘く、漏洩される

など、案外あり得ると思います。

一つのサービスで破られる可能性が低くても、「どれか一つでも破られる」可能性となると、無視できないくらい大きくなります。

### メリット

 - 一つのサービスに限れば、破られにくい
 - なんとか覚えていられる

###デメリット

 - 一個破られたら他も全部破られる


#サービスごとに別々のぐちゃぐちゃな文字列にして、どっかにメモる(現実的か)

サービスごとに別々のランダムな文字列をパスワードに設定するということです。

それらを全部記憶できれば理想ですが、無理なので、どっかにメモります。

破られる可能性は低いし、一つ破られたとしても他がまとめて破られることはないので、良さそうです。

でも、そのメモを見られたら終わりですね。

紙にメモるなら紙を見られたら終わりですし、スマホやPC内にメモってもそれを見られたら終わりです。


恐らくはそこに全てのパスワードをまとめてメモるでしょうから、まとめて全サービス破られます。


また、その「メモ」を紛失したら、一切のログインができなくなるというリスクがあります。


私は、メモを見られるリスクより、なくすリスクの方が大きいような気がします。

メモが紙でも電子でも、なくすリスクは結構大きいと思います。

でも紙か電子かで言ったら、入力の手間を考えると、紙よりもコンピュータ上のどこかにメモっておくほうが良いと思います。

コピペで入力すれば、入力間違いもないですしね。

###メリット

 - 破られにくい
 - 一つ破られても他が破られることはない

###デメリット

 - パスワード入力のたびにメモが必要
 - メモを紛失したら終わり


#ぐちゃぐちゃな文字列を覚え、サービスごとに違う文字列を足す(現実的か)


例えば「dGs$d832●●●●●fvSF#sFW」みたいな**マスターキー**を記憶しておいて、

実際のパスワードは、yahooなら「dGs$d832 **YAHOO** fvSF#sFW」にする、という感じ。

これならパスワードそのものも破られにくいし、パスワードの使いまわしもしていません。

…ただ、使い回しはしていないものの、「一つ破られたら他も破られる」の対策になっているかどうかは疑問が残ります。


まったく同じパスワードを試してすぐ諦めてくれるのならいいのですが…


上記の例だったら、「YAHOO」の部分を「FACEBOOK」に変えればFacebookにログインできると推測できます。


サービス名をパスワードに入れ込む時のルールを複雑にして

「dyGAsh$Odo832fvSF#sFW」
「d **y** G **A** s **h** $ **O** d **o** 832fvSF#sFW」

のようにすればマシになりますが、攻撃者はそのくらい試してくるでしょう。

ここで言う「試す」というのは手動で一つずつためすのではなく、いろんな変換規則が既にプログラムとして表現されていて、それらを高速で実行してパスワードを生成し、試す、ということです。

セキュリティの専門家でもない我々が思いつくような「変換規則」は、攻撃者はとっくに知っていると考えたほうが良いです。

###メリット

 - なんとか覚えていられる
 - 破られにくい

###デメリット

 - 一個破られると他も(恐らく)破られる

#パスフレーズ(現実的か)

こちらはまだ最近使われるようになった言葉で、意味の定まった言葉ではないと思いますので、ここでは

「複数の単語を並べて作った長い文字列」のこととします。

パスワードの安全性は文字数を長くすることで増します。パスフレーズは文字数がとても多くなるので、効果的とされています。


例えば、「certainlydeadacuteliteralholidaytwentyresemblancekeeping」のようなものをパスワードとして設定するわけです。

ちなみにこれは8単語で、56文字です。長いですね。

仮にパスフレーズを全てアルファベット小文字で作る場合でも、1.7*10^79通りのパターンがあります。

一つ心配なのが、攻撃者が、いろんな単語の並びを試す「単語単位のブルートフォースアタック」を使ってきた場合ですが、

仮に英単語を10万語(ジーニアス英和辞典第５版の収録語数が約10万5000)だとすると

8単語だと、$10^{40}$通りの組み合わせがあります。

これは、通常のパスワード20文字分の強さです。これは十分強いと言って良い気がします。
(使える文字数をアルファベット大文字小文字、数字、記号32種の合計92文字とした場合、20文字で$2.9 \times 10^{39}$通り)

あとは、このパスフレーズをどうやって覚えるのかという問題が残ります。

ランダムな単語の並びを一つ暗記しても、それを全てのサービスに使ったら意味がありませんし

サービス名を混ぜ込んで違う文字列に見せかけたところで、「攻撃者もいろんな変換規則を試してくる」ことへの対策になっていません。

パスフレーズは、単体のパスワードとしては強いですが、運用管理の点で、理想ではないように思うのですが、どうなのでしょう。

また、サービスが長いパスワードを受け付けてくれるかどうかという問題もあります。

###メリット

 - なんとか覚えていられる
 - 破られにくい

###デメリット

 - 長いパスワードが設定できない可能性がある
 - 一つ破られたら他も(恐らく)破られる

#パスワード管理アプリを利用する(現実的か)

「One Password」あたりが有名でしょうか。

覚えなくていいし、強力で破られにくいパスワードを生成してくれるし、一個破られても他がまとめて破られることもない。

まさに理想的に思えます。

が、これも3つほど欠点があると思います。

###そのサービスの運営者を信用できるかどうかはユーザー判断

欠点1つ目です。サービスの運営者がパスワードを悪用したら終わりです。

ただこれは、信用すると決断してしまえば解決する話でもあります。

この記事の前提にも「ブラウザや端末の提供者は信用するものとする」と書いたように、

ある程度サービス提供者を信用して、その人に裏切られたなら諦める、という割り切りはどうしても必要です。

###そのサービスがトラブったら終わり

欠点2つ目です。

パスワードそのものを自分が把握していないので、そのパスワード管理アプリが不具合で動かなくなったり、運営会社の方針が変わったり、そもそも倒産したりしてサービス提供がされなくなったら、あらゆる他のサービスへのログインができなくなってしまいます。

この対策としては、生成したパスワードを手元にも保管しておけば良いですね。

入力するときはそこからコピペしましょう。


###PCやスマホをまたいで使おうとすると有料なことが多い

欠点その3です。これは大きいと思います。パスワード管理にお金を使いたいと思えるかどうか。

###メリット

 - 覚えなくていい(マスターアカウントのパスワードは覚える必要があるかも)
 - 破られにくい
 - 一つ破られても他が破られることはない

###デメリット
 - サービス提供者を信頼するかどうかという問題がある
 - サービスが提供されなくなる恐れがある(手元でパスワードを保管することで対策)
 - 有料なことがある

#ぐちゃぐちゃな文字列を一つ覚え、サービスごとに違う文字列を足し、一方向ハッシュ関数を通す(現実的か)

実はこの記事で一番押したい方法はこれです。

私が採用している方法もこれです。

ただし「一方向ハッシュ関数って何？」という理解が必要なので少しだけ難易度が高いです。

『一方向ハッシュ関数』とは、「文字列を渡すと、それを元にぐちゃぐちゃな文字列を作ってくれるもの」です。(厳密には文字列ではなくバイナリ)

2ch(現在は5ch)のスレを見る方は「トリップ」と言えばピンとくるかもしれません。

一方向ハッシュ関数は以下の特徴を備えています

 - 出力結果から元の文字列が推測できない
 - 元の文字列が同じなら、出力結果も必ず同じ
 - 元の文字列が異なるなら、出力結果も(非常に高い確率で)異なる

先程使った例をもう一度使いましょう。

「dGs$d832●●●●●fvSF#sFW」みたいな**マスターキー**を記憶しておいて、

サービス名を足して「鍵」を作ります。yahooなら「dGs$d832YAHOOfvSF#sFW」にする、という感じ。先程はこれをこのままパスワードとしましたが…

この文字列を一方向ハッシュ関数に通すと「xJE1rozY01WNfyZSH3yZeOQ1xeL7u25vTh+/T+Foc7I」のようになります。

Facebookなら
「dGs$d832FACEBOOKfvSF#sFW」をハッシュ関数に通し「E6ORJpHcIwna+GHMqvZKh0PkTwUtJuZvO3HlwInVty0」となります。全然違いますね。

こうして作ったぐちゃぐちゃな文字列の最初の何文字かをパスワードとして使えば良いわけです。サービスにもよりますが、16〜30文字くらいですかね。

ここから元の文字列を推測することは不可能なので、仮にこのパスワードが漏れても他のサービスまで破られることはありません。

## 既によく知られているアルゴリズムを使っている

また、この方法のいいところは

「既によく知られているアルゴリズムで変換している」という所です。

今回の例では、具体的には「UTF8でエンコードした文字列を」「SHA-256という一方向ハッシュ関数を通し」「base64で文字列にする」という工程になっています。

全て既によく知られたアルゴリズムであり、**特定のサービスに依存していません**。

実際この記事を書く時も、[こちらのサイト](https://approsto.com/sha-generator/)で変換しましたが、別に[こちらのサイト](https://quickhash.com/)でもいいし、自分でプログラムを書いたっていいわけです。

なので、仮にどこかのサービスが使えなくなっても困らないわけですね。



##日本語も使える

UTF-8は半角英数以外の文字も扱えるので、変換する前の「鍵」は日本語を含んでも構いません。

「わたしはyahooにログイン！！したいぜ〜〜」
↓
「olzk3CjNgUKo+I3PWIQ/zWDeSqoJXQ6we2vCNH6q5i0」

のように変換できます。

一文字でも違うと…

「あたしはyahooにログイン！！したいぜ〜〜」
↓
「zTvwkuLZEIfYpFuAm2SeCldFiE8mUjH9NIr+bcPnHzM」

のように、全然違う結果になりますね。もとの文字列を推測する方法は存在しないわけです。

##変換サービス

使える変換サービスへのリンクをいくつか貼っておきます


https://hogehoge.tk/tool/
https://approsto.com/sha-generator/
https://hash.online-convert.com/sha256-generator
https://quickhash.com/

「1」を変換して「a4ayc/80/OGda4BO/1o/V0etpOqiLx1JwB5S3beHW0s=」になれば、そのやり方で合ってます。最後の「=」はあったりなかったりします。



##変換サービスの運営者を信頼するかどうか

ただし、この方法にも注意点があります。


変換サービスの運営者が、「入力された文字列」を保存していたら終わりです。「鍵」がバレます。

結局、パスワード管理に何かツールを利用する場合、そのツールの提供者を信用できるかどうかという問題が常に付きまとうわけですね。

###メリット

 - 覚える文字列は一つなのでなんとか覚えていられる
 - 破られにくい
 - 一個破られても他が破られることはない
 - 特定のサービスが提供されなくなっても困らない

###デメリット

 - 入力の度に変換の手間がかかる
 - 変換サービス提供者を信頼できるかどうかという問題がある(自分でプログラムを書けば解決)


#変換アプリ作りました

![PasswordCalculatorHeader.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85139/6300c2db-9f57-305e-81a2-ffa63f9bea54.png)


[パスワード計算機(Web)](https://password-calculator.web.app/web/#/)

[パスワード計算機(Android)](https://play.google.com/store/apps/details?id=work.oka_ryunoske.password_calculator_flutter)

[パスワード計算機(iOS)](https://apps.apple.com/app/id1492432603)

ということで、上記のアルゴリズムで好きな文字列からパスワードを生成するアプリを作りました！

文字数を指定して、その文字数だけパッとコピーして貼り付けられます！

記号が必須の場合は、記号を含むまで取り出す文字を後ろにシフトします。

記号禁止の場合は記号を取り除きます。

パソコンでもスマホでも、同じパスワードをさくっと生成してコピペできます！

###メリット

 - 覚える文字列は一つなのでなんとか覚えていられる
 - 破られにくい
 - 一個破られても他が破られることはない
 - 生成したパスワードを簡単にコピペできる
 - ぼかしがかかっているので後ろから画面を見られてもパスワードは見えない
 - このアプリが使えなくなっても他のサービスで代用できる(自分で特定の文字数を切り出したりする手間はかかる)

###デメリット

 - 入力の度に変換の手間がかかる
 - サービス提供者の私を信用できるかという問題が残る

最後のデメリットはどうしても付きまといますね。

私は、このアプリへの入力内容や生成結果を端末に保存したりどこかに送信したりしないことをお約束します。

でも、私がこの約束を絶対に守るということを証明する方法は存在しないので、信用するかどうかは利用者次第ということになります。

あとは、自分でプログラムを組むしかないですね。




#参考
この記事は下記の記事を大いに参考にしました。
https://sekika.github.io/2017/05/09/Password/

#さいごに

筆者はセキュリティの専門家ではありませんので、この記事内のセキュリティの考え方が誤っている恐れがあります。もしお気づきの場合は教えていただけると嬉しいです。