いろいろなサイトの複雑なパスワードを安全に管理するためには、どうするかという話。
パスワード管理用のソフトやアプリは色々あり、それで管理しているという人も多いだろう。しかし、ある特定のソフトに依存するということは、そのソフトの開発者が信頼できるか、パスワードは安全か、突然ソフトが使えなくなってパスワードにアクセスできなくならないか、といったような不安もある。
そこで、パスワードのリストを作成して、そのファイルを暗号化して保存している、という人もいることだろう。
ハッシュによるパスワード生成
ここでは、「サイト固有のパスワードの種」をファイルに保存しておいて、「記憶しているマスターパスワード」と決められたハッシュアルゴリズムから、サイトのパスワードを都度生成する、という方法について書く。
C(H(M + S)) = P
H: ハッシュ関数
C: ハッシュをパスワード文字列に変換する関数
M: 記憶しているマスターパスワード
S: サイト固有のパスワードの種
P: サイトのパスワード
この方法は「パスワードを暗号化して保存する」方法よりも総当たり攻撃に強いという特徴がある。試みに適当なマスターパスワードを入力したときに、生成されたパスワードが正しいか否かは「実際にサイトにログインを試みないとわからない」ためである。
Python 3 版のプログラム
Python 3 で書いたそのようなプログラムを公開している。
プログラムに直接「サイト固有のパスワードの種」を書いて使用する。サンプルとして、google, amazon, twitter の「サイト固有のパスワードの種」を入れてある。
このプログラムを password という名前としてパスが通っているところに保存して、
password google
として起動すると、
マスターパスワードを入力してください。
と表示されるので、そこで自分が決めたマスターパスワードを入力すると、パスワードが表示される。クリップボードにコピーするように設定することもできる(ソースコード参照)。
サイトごとの情報は、プログラム冒頭で辞書オブジェクトとして
sitekey = {
"google" : ["sha512", "an", 16, "kKkMqYDUIivWLi3WSt3VndHci"],
"amazon" : ["sha3_384", "an", 16, "stBuQIQgT9Yp84RBK3HdllnUK"],
"twitter" : ["sha3_512", "an", 14, "UmhvSHT72smO4aI1LMYt7H2el"]
}
のように定義されているのでここを書き換える。ここで、サイト固有のパスワードの種だけではなく、ハッシュアルゴリズム、パスワードの文字種(an はアルファベットと数字)、パスワードの長さも指定する。また、要素を追加すればその情報が表示されるため、たとえばサイトごとのユーザー ID や登録したメールアドレス、二段階認証に設定した電話番号などの情報を書き込んでおくことができる。さらに詳しいことは、ソースコードのコメントを参照。
せっかくプログラミングができるのであれば、自分の好きな言語でこのようなプログラムを作成して自分好みに管理するのが良いであろう。私は、自分専用のスクリプトはすべてプライベート Git リポジトリで管理して、そのディレクトリにパスを通して使用しているが、このような自分専用のパスワード生成スクリプトもそこで管理をしている。
JavaScript 版のプログラム
このプログラムの JavaScript 版を作成した。「マスター」にマスターパスワードを入れると、リアルタイムでパスワードが生成され「コピー」でクリップボードにコピーされる。jsSHAを使って SHA の計算をしている。Python 版と JavaScript 版で、同じマスターパスワードから同じパスワードが生成される。JavaScript 版では連想配列を使って
var sitekey = new Object({
"google" : ["sha512", "an", 16, "kKkMqYDUIivWLi3WSt3VndHci", "https://www.google.co.jp/", "ユーザID: xxx", "2段階認証: "],
"amazon" : ["sha3_384", "an", 16, "stBuQIQgT9Yp84RBK3HdllnUK", "https://www.amazon.co.jp/", "メール: xxx"],
"twitter" : ["sha3_512", "an", 14, "UmhvSHT72smO4aI1LMYt7H2el", "https://twitter.com", "https://twitter.com/seki/"]
});
のように定義しているので、サイトごとの情報は Python の定義をそのままコピーして使える。モバイルからアクセスする必要のあるパスワードについては、JavaScript 版でもパスワードを生成できるようにしておくと便利である。
この記事はプログラマー向けに書いたが、パスワードの管理についてには、もう少し一般の人向けに書いた。