私のパソコン雑記帖

crypt 関数の振舞い

カテゴリー: PHP
20Sep2006

クリプト関数に首を突っ込む

Basic 認証で .htpasswd というドットファイルに id と password を記述する際、最初はインターネット上で見つけた暗号化ツールを利用していましたが、さらに調べてみるとこれには crypt 関数が使われていることが分かりました。それがきっかけでこの関数を少し突っ込んでみることにしました。

Crypt Manual に目を通した結果をまとめると・・・

  1. crypt 関数の標準的な使い方は、第2引数に2文字(半角)の暗号化キーを与えるやり方です。この第2引数を"salt"と呼ぶのが通例のようです。辞書を引いても「塩」とかそれらしき言葉しか出てこない。「塩」の延長で「味付け」という意味合いで使われるのでしょうか。
  2. この標準的な使い方でハッシュ化した文字列の最初の2文字は、第2引数で与えた2文字そのものです。従ってハッシュ化した文字列を見れば使われた暗号化キーは明々白々です。
  3. 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 モードだけですが。



コメント