はじめに
ありそうなパスワードを生成するツールを作りました. こちらから遊べます.
昨今はブラウザや OS の方で強いパスワードを生成し,覚えてくれます. 私も頼りにしています.Apple 社や Google 社に裏切られたらどうしよう.
そこで,逆に,弱いパスワードを生成したくなりました.
弱いパスワードとは?
短ければ弱いです.使っている文字種が少なければ弱いです.
例えば数字 4 文字では 通りしか存在しないのに対して, 数字 8 文字では 通り存在します.
また,アルファベット小文字 8 文字では 通り,アルファベット小文字,大文字,数字を合わせたパスワードでは 通り存在します.
でパターンが増えて,探索が困難になります. 短くて文字種が少ないパスワードであれば,何でも弱いということではあります.
しかし,これでは面白くありません.
password や sakura123 の方が fauyvda や 3fe78hj より弱そうではありませんか?
実際,人間の使うパスワードはある程度の規則性があり,これを利用した辞書攻撃という手法があります.
辞書攻撃とは,よく使われるパスワードのリストをパスワードとして片っ端から入力して試す手法です. この辞書として,流出したパスワードが用いられることがあります. そのため,パスワードを複数サービスで使い回すと 1 つの流出で他のサービスも破られてしまう可能性があるのが怖いところ. やめよう,使い回し.
なお,こうしたパスワードリストとして,セキュリティ対策のための公開データセットも存在します. もちろん公開データセットを使用した悪用も可能でしょうが.
今回使ったデータセットは SecLists です.
ありがちなパスワード生成
弱いパスワードというのは先ほど書いた通り短ければ良いのか,という話になるので,ありがちなパスワード生成に舵を切りました.
できれば日本人が作りそうなありがちパスワードの生成をやりたかったのですが,Top 150 のデータセットしか見つけられなかったので断念.
今回は Pwdb_top-1000000.txt を使用しました.
どうやってこれが構築されたかはよく調べていないのでわからないのですが,名前からしてよく使用されているパスワードリストっぽく,今回の目的に適していそうなので使ってみることにしました.
MIT ライセンスなので割と好きに使えるのもうれしいところ.
直前何文字かの並びから次を予測する手法(N-gram)も試してみたが,結果としてはそれなり止まり. 加えて N-gram だと長さを制約するのが難しいという問題もありました.
そこで,Recurrent Neural Network(RNN)を使いました. 単純に次の文字を予測させるのではなく,あと何文字でおしまいかの情報も追加で入れてあげるようにしました. するといい感じの文字列を吐き出してくれるように. 最後の数文字を数字で埋めたり,とかやってくれます. さすがだな!深層学習.
学習は PyTorch で行っています. 推論は TypeScript で PyTorch と同じ動作をするようにコードを再現して書いています. 相当シンプルな構成なのでブラウザ上でも余裕でございます.
いい感じのライブラリを使えばもっと楽なんだろうなあ,とも思いつつ.
おわりに
日本人のパスワード風にするためにローマ字の特定のパターンを含むものだけ抽出,とかやってみたのですが中々納得のいくようなものができず,結局こういう形になりました.
深層学習に頼りすぎても面白くないなあと思いつつも,やっぱり強いなあ. ブラウザ上で動くシンプルな構成でも十分面白い挙動はさせられますね.
ブラウザ上で深層学習やるのは二度目かな?手書き文字分類以来ですね. word2vec とか,コンピュータが吐き出したデータで遊ぶことはあれど,深層学習使うのはあんまりやってこなかったな.
学習パラメータ
小さい RNN でございます. 一応書いておきます.
- 文字の Embedding:16 次元
- 隠れ層:2 層
- 隠れ層の大きさ:512 次元