ハッシュアルゴリズムにmd5を使っているが、
md5もはや安全ではないらしい。
このスクリプトはあくまでもハッシュを作ることを実感するためのサンプルである。
実際にはより安全なアルゴリズムに変える必要がある。
ユーザ名とパスワードを登録するcgi
register_pwd.cgi
---
#!/usr/bin/perl
print "Content-type: text/html\n\n";
print "register password";
print '<form action="save_pwd.cgi" method="post">';
print '<p>';
print 'name:<input type="text" name="username" size="20">';
print '</p>';
print '<p>';
print 'password:<input type="text" name="password" size="20">';
print '</p>';
print '<p>';
print '<input type="submit" value="送信"><input type="reset" value="リセット">';
print '</p>';
print '</form>';
---
ユーザ名とパスワードのソルト付きハッシュを保存するcgi
users.txt というファイルに保存する。
すでに同じユーザ名が登録されているかのチェックもする。
ソルトの作り方がアレかもしれないが、
ここもサンプルなので見逃してほしい。
save_pwd.cgi
---
#!/usr/bin/perl
use Digest::MD5 qw(md5 md5_hex);
if ($ENV{'REQUEST_METHOD'} eq 'POST') {
read(STDIN, $alldata, $ENV{'CONTENT_LENGTH'});
} else {
$alldata = $ENV{'QUERY_STRING'};
}
foreach $data (split(/&/, $alldata)) {
($key, $value) = split(/=/, $data);
$value =~ s/\+/ /g;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack('C', hex($1))/eg;
$value =~ s/\t//g;
$in{"$key"} = $value;
}
print "Content-Type: text/html; charset=Shift_JIS\n\n";
print "<html>\n";
print "<head><title>save password</title></head>\n";
print "<body>\n";
$my_user = $in{'username'};
$my_pwd = $in{'password'};
print "<p>username: $my_user</p>\n";
print "<p>password: $my_pwd</p>\n";
$digest = md5_hex($my_pwd);
print "md5 digest:".$digest."<br>";
$num = int(rand(1000000));
$salt = '$1$'.$num.'$';
print '<br>'.$salt.'<br>';
$crypt = crypt($my_pwd, $salt);
print "md5 with salt: ".$crypt."<br>";
print '<br>';
$count = 0;
open (IN, "users.txt");
while(<IN>){
@tmp_user = split(/,/,$_);
if (@tmp_user[0] eq $my_user){
$count++;
}
}
if ($count > 0 ) {
print("username ".$my_user." has been already registered.<br>");
}else {
open (OUT,">> users.txt");
print OUT $my_user.",".$crypt."\n";
close (OUT);
print 'registered<br>';
print '<a href="/index.html">'.'index.html'.'</a>';
}
print "</body>\n";
print "</html>\n";
exit;
---
パスワード確認cgi
(ログインのイメージ)
kensho_pwd.cgi
---
#!/usr/bin/perl
print "Content-type: text/html\n\n";
print "verify password";
print '<form action="hash_kensho.cgi" method="post">';
print '<p>';
print 'name:<input type="text" name="username" size="20">';
print '</p>';
print '<p>';
print 'password:<input type="text" name="password" size="20">';
print '</p>';
print '<p>';
print '<input type="submit" value="送信"><input type="reset" value="リセット">';
print '</p>';
print '</form>';
exit;
---
ユーザの入力したユーザ名を保存したユーザ名から検索し、
保存されているソルトを付加してハッシュを計算し、保存されているハッシュと比較する
users.txtを読んで、同じユーザ名を探す。
実際はDBを使うなどするのだろうがこれは実験なので。
---
#!/usr/bin/perl
use Digest::MD5 qw(md5 md5_hex);
if ($ENV{'REQUEST_METHOD'} eq 'POST') {
read(STDIN, $alldata, $ENV{'CONTENT_LENGTH'});
} else {
$alldata = $ENV{'QUERY_STRING'};
}
foreach $data (split(/&/, $alldata)) {
($key, $value) = split(/=/, $data);
$value =~ s/\+/ /g;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack('C', hex($1))/eg;
$value =~ s/\t//g;
$in{"$key"} = $value;
}
print "Content-Type: text/html; charset=utf-8\n\n";
print "<html>\n";
print "<head><title>password kensho</title></head>\n";
print "<body>\n";
$my_user = $in{'username'};
$my_pwd = $in{'password'};
print "username: $my_user<br>";
print "password: $my_pwd<br>";
open (IN,"users.txt");
#$record = <IN>;
$count=0;
$tmp_user="";
$tmp_digest="";
while(<IN>){
@tmp = split(/,/,$_);
if(@tmp[0] eq $my_user){
$count++;
$tmp_user = @tmp[0];
$tmp_digest = @tmp[1];
}
}
close (IN);
if($count<1){
print "unknown username<br>";
exit;
}
chomp($tmp_digest);
$salt = substr($tmp_digest,0,10);
$crypt = crypt($my_pwd, $salt);
print "md5 with salt: ".$crypt."<br>";
print "saved md5 : ".$tmp_digest."<br>";
if ($tmp_digest eq $crypt ) {
print "Welcome, ".$my_user." !!<br>";
}else{
print "Incorrect password<br>";
}
print "</body>\n";
print "</html>\n";
exit;
---
実行例
ユーザ名とパスワードを入力
保存されたソルト付きハッシュ
上に表示されているのは、ソルトなしのハッシュ
$で挟まれているのがソルト。
ハッシュの先頭に付加されるのでそれを含めて保存する。
登録したユーザ名とパスワードを入力する
保存してあるハッシュと一致した。




