MySQLのDBにMD5でハッシュ化されたパスワードが格納されているのですが、これをPerlのスクリプトで照合したいと思っています。
具体的には、DBに格納されているパスワードを用いて、Perlで作成された会員専用ページなどにログインをするといった感じです。
DBIを用いてDBからの情報を取得することはできたのですが、Perl側での対処がわかりません。
Perl側で入力されたパスワードをハッシュ化して、双方を照合するなどの情報を見たのですが、いまいち解らず認証することができませんでした。
以下にパスワードに関する部分のソースを記載させていただきます。
srand();
@salt = ( "A".."Z", "a".."z", "0".."9", ".", "/" );
$salt = '$1$' . join('', map($salt[int(rand(64))], 1..8)) . '$';
$pass = crypt($in{'pass'}, $salt);
crypt($in{'pass'},$ary) eq "$ary")
※$aryはDB内に格納されているパスワードです
Perlに関して殆ど解っていないもので、とんちんかんな記述かもしれませんが、ご教授いただけますと幸いです。
宜しくお願いいたします。
A 回答 (3件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
ANo.2です。
SALT生成が必要なのはDB格納用に最初にエンコードする場合のみです
ご質問の内容の場合、すでにエンコードされたものは配列に格納されておりますのでSALT生成は不要です。(まずは処理の内容をしっかりと把握・整理してください)
チェックのみの処理手順なら以下のようになります。($aryは$ARYとしました)
## ***************************************************************
## DB比較プログラム
## +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
## PWを取得(フォームからですね?)
my $inPW = '';
## DBから全PWを配列に格納
my @ARY = (???????????????);
## チェック用フラグ初期化
my $FLG = "false";
## 全配列をチェック
foreach my $V (@ARY){
## 暗号化パスワードから先頭2文字(SALT部分)を取り出す
my $sSALT = substr($V,0,2);
## 取得したSALTから
my $sPWD = crypt($inPW, $sSALT);
## 比較
if($sPWD eq $V){
$FLG = "true";
last;
}
## ------------------------------------------
## 上記ループ内処理の省力版:cryptは先頭2文字しか使わないのでわざわざ取り出さなくても良い
## ------------------------------------------
## my $sPWD = crypt($inPW, $V);
## if($sPWD eq $V){
## $FLG = "true";
## last;
## }
## ------------------------------------------
}
## 結果表示
if($FLG eq 'true'){
print "パスワードOK";
}else{
print "パスワードが不正です。";
}
## ***************************************************************
蛇足ながら、SALT生成が適用される新規パス登録の流れが以下のようになります。
## ***************************************************************
## DB登録プログラム
## +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
## PWを取得(フォームからですか?)
my $inPW = '';
## 塩の生成
srand();## 乱数の種仕込み
my @sTABLE = ( "A".."Z", "a".."z", "0".."9", ".", "/" );## 乱数用→文字列置換テーブル
my $sSALT = join('', map($sTABLE[int(rand(64))], 1..2));## ランダムな文字列を2文字生成
## パスワードエンコード
my $sPWD = crypt($inPW, $sSALT);
## パスワードから暗号化された文字列をDBに登録する処理:$sPWD
??????????????????????????????????????????????????
## ***************************************************************
コメントから処理の流れを読み取ってください。
あと、これが表示されるHTMLの処理によって先頭の半角スペースが無視されますが、本体への「インデント」は忘れないようにしてください。
No.2
- 回答日時:
この質問サンプルから想像した場合は、「salt」がランダムに生成エンコードされDB格納となっておりますので、DBに対しての直検索は出来ないと思います。
DB内から全ハッシュ値データを取得して、各ハッシュ値から「salt(頭2バイト分)」を抽出して、対象パスワードをその「抽出salt」で「crypt」して比較することになるかと思います。
「salt」を固定化すればDBへの直検索が可能になり、たいへん効率的なのですがそのようにしてはいかがでしょうか?
また、「salt」は先頭2バイトしか処理対照になりませんので、長いコードを生成しても無駄になります。 蛇足ですが質問サンプルでは実際に動かすと先頭2文字は必ず'$1'となりますので・・・
ご参考までに
## 塩の生成
srand();
my @salt = ( "A".."Z", "a".."z", "0".."9", ".", "/" );
my $salt = '$1$' . join('', map($salt[int(rand(64))], 1..8)) . '$';
print $salt;
print "\n";
## パスワード「TESTTEST」で実験
my $pass = crypt("TESTTEST", $salt);
print $pass;
print "\n";
## エンコードされた文字から塩を取り出し
$pass =~ m/(^..)*/;
my $new_salt = $1;
print $new_salt;
print "\n";
## その取り出した塩でもう一回エンコード
my $new_pass = crypt("TESTTEST", $new_salt);
print $new_pass;
print "\n";
この回答への補足
ご教授頂きまして有難うございます。
お教え頂いたソースを参考にさせて頂いたのですが、少し私では理解できなくてお恥ずかしいのですが、まだ解決に至りませんでした。
## 塩の生成
srand();
@salt = ( "A".."Z", "a".."z", "0".."9", ".", "/" );
$salt = '$1$' . join('', map($salt[int(rand(64))], 1..8)) . '$';
$pass = crypt("$in{'pass'}", $salt);
#html表示
print <<"EOM";
<form>
名前 <input type="text" name="name"><br>
パスワード <input type="password" name="pass">
</form>
EOM
## エンコードされた文字から塩を取り出し
$pass =~ m/(^..)*/;
$new_salt = $1;
## その取り出した塩でもう一回エンコード
$new_pass = crypt("$in{'pass'}", $new_salt);
if (crypt($new_pass,$ary) eq "$ary") {
$flag = '0'; #認証OK
}
大まかにですが、上記のような感じにしたのですが、とんちんかんな事を記述していたら申し訳ございません。
何か根本的に間違っているのでしょうか?
何度も申し訳ございませんが、ご教授頂けますと幸いです。
No.1
- 回答日時:
そういう場合は、PerlからDBIを使い、sqlを発行したほうがいいです。
入力されたパスワードをMD5でselectします。
$sql = "select * from table where pass = MD5('" .$in{'pass'} ."')";
この回答への補足
ご教授頂きまして有難うございます
現在DBに関する記述の中で、
$sth = $dbh->prepare("SELECT name,pass FROM テーブル名");#DBの中の#nameとpassがほしい
上記に、
$sth = $dbh->prepare("SELECT name,pass FROM テーブル名 where pass = MD5('" .$in{'pass'} ."')");
このように記述すればよいのでしょうか?
ただ、これではうまく動作をすることができず、少し私では理解できなくてお恥ずかしい限りです。
何度も申し訳ございませんが、具体的な記述方法などをお教えいただけますと幸いです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- PHP DBのハッシュ化したパスワードをpassword_verifyで戻し照合したのですが上手く行きません 2 2023/02/06 13:24
- PHP 重複を防ぐ記述について教えて下さい。 3 2023/04/03 14:35
- Perl perlでリテラル値はメモリにどのように格納されているか? 1 2023/01/15 20:45
- その他(開発・運用・管理) Windowsバッチファイルでリモートデスクトップを自動ログインするが確認画面が出る対処方法 1 2022/12/19 15:48
- PHP PHPのエラーの解消法について教えて下さい。 1 2023/02/06 10:48
- Visual Basic(VBA) ACCESS DAO で不要なテーブルのフィールド(列)の削除 4 2022/06/23 12:13
- PHP php ログイン 1 2022/11/01 00:24
- その他(プログラミング・Web制作) laravel 本番環境でメールが送れません。 1 2023/02/17 17:57
- Perl perlをバージョンアップしたら、今まで正常に動いていたプログラムが、エラーになってしまった 3 2022/10/05 15:44
- 予備校・塾・家庭教師 塾 オンライン授業について 通っている塾にもう1教科プラスする事になり オンライン授業を始める事にな 1 2023/08/08 21:56
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Perlで特定文字列から特定文字...
-
テキストファイルで提出とは?
-
openした後、closeしないでプロ...
-
Perlのエラーについてご教授く...
-
perlの構文でカンマの意味が分...
-
Perl の外部モジュールの利用方法
-
Perlでsprintf("%02d",$month)...
-
Perlでの文字列置換
-
フローチャート 九九
-
perl LWPでURLにアクセスした時...
-
perl 初等プログラミングについて
-
Perlで、「が」を、「...
-
Windows版のPerlについて
-
このファイルを開く方法で困っ...
-
アルファベットに付いて質問し...
-
#!/usr/bin/perlで書きだしたCG...
-
perlのflock関数でロックをかけ...
-
AI sisterとは、偽物の人ですか?
-
bashスクリプト
-
ファイルアイコンの左下に緑の□...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
INDIRECT 横に再度抽出したい
-
perlをバージョンアップしたら...
-
openした後、closeしないでプロ...
-
Perlで特定文字列から特定文字...
-
Wallpaper Engineでおすすめの...
-
Perlのエラーについてご教授く...
-
アルファベットに付いて質問し...
-
Strawberry Perl for Windows ...
-
bashスクリプト
-
テキストファイルで提出とは?
-
Perl の外部モジュールの利用方法
-
#!/usr/bin/perlで書きだしたCG...
-
Windows10においての『Perl』の...
-
perlのflock関数でロックをかけ...
-
perlで2次元配列をサブルーチ...
-
Perlで時間の計算
-
perlのrequireの動き方について...
-
画像が表示でnull; this.src
-
ターミナルで特定の文字と文字...
-
英数文字列のうちの数値を4桁に...
おすすめ情報