crypt 関数の振舞い
カテゴリー: PHP 20Sep2006
クリプト関数に首を突っ込む
Basic 認証で .htpasswd というドットファイルに id と password を記述する際、最初はインターネット上で見つけた暗号化ツールを利用していましたが、さらに調べてみるとこれには crypt 関数が使われていることが分かりました。それがきっかけでこの関数を少し突っ込んでみることにしました。
Crypt Manual に目を通した結果をまとめると・・・
- crypt 関数の標準的な使い方は、第2引数に2文字(半角)の暗号化キーを与えるやり方です。この第2引数を"salt"と呼ぶのが通例のようです。辞書を引いても「塩」とかそれらしき言葉しか出てこない。「塩」の延長で「味付け」という意味合いで使われるのでしょうか。
- この標準的な使い方でハッシュ化した文字列の最初の2文字は、第2引数で与えた2文字そのものです。従ってハッシュ化した文字列を見れば使われた暗号化キーは明々白々です。
- crypt 関数は、CRYPT_STD_DES、CRYPT_EXT_DES、CRYPT_MD5 、CRYPT_BLOWFISH と4っつのハッシュモードをサポートします。ただし、使用しているサーバーが対応している限りにおいて、ということ。ちなみに上記標準モードは STD_DES 。
自分のサーバー環境では何が使える?
<?php
if (CRYPT_STD_DES) { print "Standard DES<br>
"; }
if (CRYPT_EXT_DES) { print "Extended DES<br>
"; }
if (CRYPT_MD5) { print "MD5<br>
"; }
if (CRYPT_BLOWFISH) { print "BlowFish<br>
"; }
?>
を走らせると容易に分かります。自分のサーバー環境(参照サイト・プロフィール)では STD_DES と MD5 がサポートされていました。更に突っ込んでみます。
STD_DES と MD5 の使い分けは第2引数の与えかたで決まります。第2引数を与えない場合は MD5 でハッシュされます。最初に "$1$"が付きますが毎回異なる暗号化文字列が返されます。
第2引数が英数字で始まる文字列の場合は STD_DES ハッシュされます。いくら長い文字列を与えても最初の2文字だけが使われます。いわゆる crypt 標準モードです。ところが第2引数が"$"で始まる文字列の場合は MD5 でハッシュされるようなのです。
第2引数に"$"で始まる文字列を与えた場合
寄り道で、次のようなテストプログラムを走らせてみました。$pwd を一旦ハッシュ化(MD5)、これを第2引数にして(1文字ずつ増やしながら)、$pwd に crypt をかけます。最後に比較のため $pwd を単純に MD5 変換したものも取り出してみました。
<?php
$pwd="testtest";
$pwd1=crypt($pwd);
$strlen=strlen($pwd1);
for ($i=1;$i<=$strlen;$i++) {
$pwd2=substr($pwd1,0,($i));
print "pwd".$i."->".crypt($pwd, $pwd2)."<br>
";
print "md5->".md5($pwd)."<br>
";
?>
結果・・・2文字以上を引数にした場合全て "$1$" で始まる MD5 ハッシュでした。また最初の10文字までは引数として使われますがそれ以降は無視される(同一結果が得られる)。crypt 関数の MD5 モードと、通常の MD5 ハッシュとは関連が無いようにみえます。
pwd1->$$h37XzUCLvvE
pwd2->$1$$h9/lcQOqPUpqtNZ8/pEH81
pwd3->$1$$h9/lcQOqPUpqtNZ8/pEH81
pwd4->$1$B$JofUMIgIgKroiHpAl8Ssq.
pwd5->$1$BK$lqEzJepnLaDFvNPMt3L68.
pwd6->$1$BKZ$ocXddruIjVjDlxuEI8GiM1
pwd7->$1$BKZZ$Fgxu3ohLTHqtSjpMRE6Sr0
pwd8->$1$BKZZY$6FC1VyM9Ryvevk964zOKK/
pwd9->$1$BKZZYS$YQu7jnh5D60JMN8netiCS.
pwd10->$1$BKZZYSm$rRfFSyMx57HvGmmfnZgEr/
pwd11~34>$1$BKZZYSmS$vpOWp6TahV7ZlMNa5jiQl.
md5->05a671c66aefea124cc08b76ea6d30bb
ということで、まずは crypt 関数の基本的な振る舞いに慣れ親しみました。とはいっても、STD_DES、MD5 モードだけですが。
|