単方向ハッシュ関数を用いパスワードを暗号化

有名どころでいえばMD5やSHA系などが挙げられますが、今回は簡単なDESベースのcrypt()関数を用い、平文のpassword,saltからハッシュ値を計算する方法です。ハッシュ値は不可逆などと言われていますが、突破されたなんて話もよく聞きます。それぞれの強度云々よりも攻撃者にどのハッシュアルゴリズムを使っているか分からないようにする方が大事です。

crypt(password,salt)関数
■password:平文のパスワード ※8文字まで
■salt :.(ドット)+/(スラッシュ)+a~z(小文字)+A~Z(大文字)+数字 ※2文字以上は切り捨て
saltの値を指定しなかったり、スペースを使った場合.(ドット)として認識されます

perlでcrypt()関数を使うコードを書いてみます(DES)
hash.pl

#!/usr/bin/perl
$password = "qwerty";
$salt = "Aa";
$hash = crypt($password, $salt);
print "$hash\n";
平文のパスワードには『qwerty』,saltには『Aa』を使いました

hash.plを実行してみます

MacBookAir:PerlProgram ****$ chmod 744 hash.pl
MacBookAir:PerlProgram ****$ ./hash.pl
AaBEDDC6pJ05s

表示された先頭の2文字はsaltの値で、残りの後ろの文字列が生成されたハッシュ値となります。11文字の固定長であること・重複無しの疑似乱数であることを確認するために、passwordやsalt値の変更行います。変更内容を確認し易くできるよう、コマンド行で実行することにします。

MacBookAir:~ ****$ perl -e '$hash = crypt("qwerty", "Aa"); print "$hash\n";'
AaBEDDC6pJ05s
MacBookAir:~ ****$ perl -e '$hash = crypt("qwerty", "aA"); print "$hash\n";'
aA6pa9vRKNpI2
MacBookAir:~ ****$ perl -e '$hash = crypt("qwerty", "ss"); print "$hash\n";'
ssSQHFRpm90Gk
MacBookAir:~ ****$ perl -e '$hash = crypt("qwerty", "qb"); print "$hash\n";'
qbfXBPzlIwoZQ
MacBookAir:~ ****$ perl -e '$hash = crypt("qwerty", "//"); print "$hash\n";'
//uyslmZi4QZY

同じ平文のパスワードでもsalt値が違えば生成されるハッシュ値が変わることが確認できました。salt値に使える文字列は4000通りほどあり、それぞれ違った値を生成できるわけです。しかもpasswordには8文字まで入力できるので、考えられるハッシュ値は数えるのが大変なほど。

MD5でのsalt値には先頭に『$1$』を付けて0~8文字(9文字以上は切り捨て)で設定できます。これでDESより多くの値を設定できるようになりますが、5~6年以上前には突破されていたと記憶しています。


攻撃者にパスワードファイルを奪われた場合、ハッシュ値から平文パスワードを手に入れることは難しい。そこで辞書攻撃や総当たり攻撃が使われます。
総当たり攻撃
パスワードに使える文字が100あるなら100^8通り全てを試す方法。必ず解析可能だが、時間はかかる。
辞書攻撃
よく使われるパスワードなどをファイルなどに保存しておき一致を探す方法。解析可能か分からないが、短時間。
例を下に

qwerty
admin
123456
password