2

私はこのコードをSOに関する非常に役立つ回答の束からほぼ逐語的に引用したので、何が悪いのか頭を悩ませることはできません。

まず、ユーザーアカウントを作成するための私の機能は次のとおりです。

function BFcrypt($password,$cost)
{
    $chars='./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    $salt=sprintf('$2a$%02d$',$cost);
    for($i=0;$i<22;$i++) $salt.=$chars[rand(0,63)];
    return array(
            'salt'=>$salt,
            'hash'=>crypt($password,$salt)
            );
}

次に、ユーザーがログインするとき:

case 'login':
    $login  =$_POST['login'];
    $pwd    =$_POST['pwd'];
    $sql    ="SELECT * FROM `users` WHERE `users`.`login`='$login' LIMIT 1;";
    if($query = mysql_query($sql)){
            $row=mysql_fetch_assoc($query);
            print_r($_POST);
            print_r($row);
            $hash = $row['password'];
            if(crypt($pwd,$hash)==$hash){
                echo"SUCCESS";
            }else{
                echo"FAILURE";

            }
    }

ログイン機能は常に失敗しているようです。$ pwd、$ hash、crypt($ pwd、$ hash)を表示するように設定しましたが、何らかの理由でcrypt($ pwd、$ hash)が==$hashに見えないようになっています。

サンプルユーザーのデータベースの行を次に示します(ソルトをログに記録していますが、ハッシュに含まれているはずです。

'id'=>'680',
'login'=>'argh',
'password'=>'$2a$10$BWZAX7wrwQp5iyK4kh6VLunqy82eiXg7GaDs6mJLqdgT5s2qiUqYW',
'salt'=>'$2a$10$BWZAX7wrwQp5iyK4kh6VL5',
'first'=>'argh',
'last'=>'argh',
'zip'=>'00000',
'email'=>'argh',
'date updated'=>'2012-12-12 16:05:29'

crypt($ pwd、$ hash)を呼び出すと、$ hashが切り捨てられ、元の22文字のソルト(およびプレフィックス)のみが残るため、$pwdが$hashである限り、出力は$hashと同じになると思います。同じ。ここで、記録しているソルトがハッシュに追加されるソルトよりも1文字長いという問題があることは明らかですが、ブローフィッシュには適切な長さであり、とにかく、1文字短くすることはできません。 tは役立つようです。

ここで何が間違っているのか理解できません。どんな助けでもいただければ幸いです。

4

1 に答える 1

2

自分のソルト値とパスワードに基づいて'argh'、小さなテストスクリプトを実行しました。

$hash = crypt('argh', '$2a$10$BWZAX7wrwQp5iyK4kh6VL5');
// $2a$10$BWZAX7wrwQp5iyK4kh6VLuIzJHihvZTdfpRXNkTPVKkTiGfLDl1RO

var_dump(crypt('argh', $hash) == $hash);
// bool(true)

あなたが示したコードには問題がないようです。

データベースのフィールド幅をチェックして、パスワードハッシュを保存できます。パスワードハッシュは少なくとも60幅である必要があります。そして、その間に、SQLインジェクションの脆弱性を修正します(プリペアドステートメントを使用するのが最も望ましいです)。

于 2012-12-13T08:52:42.347 に答える