セキュリティの問題で今まで躊躇してたMoneyForward をついに始めた。 せめてものリスクを最小化するために、MFと銀行口座のパスワードを、推測できないランダムな文字列にすることにした。
しかしながら、Webサイトごとに異なるランダムな文字列を全て覚えるのは現実的ではないため、パスワードマネージャを用いる必要がある。 主なパスワードマネージャには、次のような物がある:
1 は、他のデバイスとパスワードが共有できないため、不便である。 2は、クラウドにパスワードを預けることはやはり漏洩のリスクが伴うし、クラウドサーバーが落ちるとログインできなくなってしまうおそれがあるなど、 自分の手の届かないところが単一障害点となってしまうことが問題である。
そこで、
- サイトごとのパスワードを、マスターパスワードとURLのハッシュで生成する
- 生成ロジックを、ブログ等で大々的に公開する
ことで、サーバーが落ちた場合でも、マスターパスワードから生成ロジックによってパスワードを再生成できるようにすることを考える。
マスターパスワードの作成
この方法で大切になるのはマスターパスワードの安全性である。 人間、そこまでランダムな文字列というものは作れるものではないし、完全にランダムな文字列は覚えづらい。 そこで、文字のマトリクスを作り、そこに図形を描いて覚えるようにする。
マスターパスワードの生成
seed の値は秘密にする必要はない。例えば、yyyymmdd
形式で表した生年月日を用いる。
得られるマトリクスは、例えば、seedが空文字列の場合、次のようになる。
$ openssl dgst -sha256 -binary /dev/null | base64 | fold -7 | sed -e 's/./ &/g' 4 7 D E Q p j 8 H B S a + / T I m W + 5 J C e u Q e R k m 5 N M p J W Z G 3 h S u F U =
当然であるが、マトリクスの上に描く図形はなるべくランダムで覚えやすいものとする。 私の場合、何故か覚えている子供の頃の実家のトイレの壁の汚れの模様を意匠化したものとした。 (実家のトイレはリフォームしたので、その壁の汚れはもう残っていない。)
マスターパスワードの長さは14文字以上にする。 詳しくは後述する。
サイトごとのパスワードの生成
サイトごとのパスワードは、 サイトのFQDN (URL の https://xxxx/bbb の xxx の部分) とマスターパスワードからハッシュ関数により生成する。
サイトパスワードの生成
このようにサイトのパスワードを作成することで、 あるサイトのパスワードが漏洩した場合でも別のサイトのパスワードが推測されることはないうえ、 マスターパスワードさえ忘れなければ何度でも再生成できる。
マスターパスワードの長さ
マスターパスワードは何文字以上が良いであろうか。 あるサイトのパスワードが漏洩した場合でも、マスターパスワードや他のサイトのパスワードが実質的に漏洩しない安全性が必要である。
SHA-256 はBitcoin のPoWで使われていることでも有名である。 つまり、SHA-256 ハッシュの計算量はマイニングパワーとして取引されており、 「1ハッシュ=〇〇円」という値段がついている。
このサイトによれば、 1ギガハッシュ/秒で1週間マイニングすると、平均0.006559ドル(≒0.7円)の報酬が得られるという計算になる。 つまり、ビットコインをマイニングすれば、1 [GH/s] ÷ 0.7[円/週] = ハッシュごとに、約1円の報酬が得られることになる。
私の資産(高々数百万円)をリスクを犯して奪うために、1億円分の計算をすることは考えられないため、 回のハッシュ関数を計算しなければ破れないパスワード長とすればよい。
seed によって異なるが、マトリクスに現れるunique な文字の種類は30種類程度なので、長さLのマスターパスワードは通りである。サイトのパスワードを1回計算するのに、N=1000回のハッシュ計算が必要なので、
よって、マスターパスワードは14文字以上が安全である。
資産がもっと多いよって人は、 なので、 資産が3桁増えるごとにマスターパスワード長の下限を2文字増やすとよい。