1

サイトにログインするときにパスワードを検証しようとすると、深刻な問題が発生します。以下のコードを使用して、php を使用してソルトでフグ暗号化パスワードを作成しています。

<?php
function cryptPass($p, $rounds = 9) {
$salt = "";
$saltChars = array_merge(range('A','Z'),range('a','z'),range('0','9'));
for($i = 0; $i < 22; $i++){
    $salt .= $saltChars[array_rand($saltChars)];    
}
return crypt($p, sprintf('$2y$%02d$', $rounds) . $salt);
}
?>

これは正常に機能し、暗号化されたパスワードが私の mysql データベースに入れられます。問題はログイン時であり、検証されません。これはログイン スクリプトです。

if(isset($_POST["u"])){
 // CONNECT TO THE DATABASE
 include_once("php_includes/db_connect.php");
 // GATHER THE POSTED DATA INTO LOCAL VARIABLES AND SANITIZE
 $u = mysqli_real_escape_string($db_connect, $_POST['u']);
 include_once("php_includes/hasher.php");
 $p = (cryptPass($_POST['p']));
 // GET USER IP ADDRESS
$ip = preg_replace('#[^0-9.]#', '', getenv('REMOTE_ADDR'));
 // FORM DATA ERROR HANDLING
 if($u == "" || $p == ""){
     echo "login_failed";
    exit();
 } else {
 // END FORM DATA ERROR HANDLING
     $sql = "SELECT id, username, password FROM users WHERE username='$u' AND activated='1' LIMIT 1";
    $query = mysqli_query($db_connect, $sql);
    $row = mysqli_fetch_row($query);
     $db_id = $row[0];
     $db_username = $row[1];
    $db_pass_str = $row[2];
     if($p != $db_pass_str){
         echo "login_failed";
        exit();
     } else {
//goto the users account

受信したユーザー データに対して cryptPass 関数を実行するべきではありませんか?

また、mysql データベースのパスワード列が VARCHAR(255) として設定されているため、十分なスペースがあることにも注意してください。この時点で、パスワードは正しく暗号化されていますが、データベース内のパスワードと正しく比較できません。php.net がアドバイスするように、md5 から離れたいと思っていました。どんな助けでも大歓迎です。これを読んでくれてありがとう。

4

2 に答える 2

1

crypt()PHPのmanページにあるものとして、もう少し詳細なデモンストレーションを次に示します。

// Only for demonstration, see mcrypt_create_iv() for a better salt:
//   http://php.net/manual/en/function.mcrypt-create-iv.php
$salt = substr(sha1(date('r')), rand(0, 17), 22);
$cost = 10;
$hash = '$2y$' . $cost . '$' . $salt;
$pass = 'mypass';
$notpass = 'notmypass';

$hashed = crypt($pass, "$hash");

echo "
Hash:
$hash

Hashed:
$hashed

Verified: 
" . crypt($pass, $hashed) . "

Not Verified: 
" . crypt($notpass, $hashed);

https://ignite.io/code/51323c3aec221e7b73000000

これは(少なくとも今回は)次のようになります。

Hash:
$2y$10$a80ded6289240c2e41a5e4

Hashed:
$2y$10$a80ded6289240c2e41a5euUFPvmt.sb6lBwOE.JTAdxQsDWmmM.Me

Verified: 
$2y$10$a80ded6289240c2e41a5euUFPvmt.sb6lBwOE.JTAdxQsDWmmM.Me

Not Verified: 
$2y$10$a80ded6289240c2e41a5euj06Emi8HigWM6BpqVFZ.ZtpA9wK5c8G
于 2013-03-02T17:52:52.773 に答える
0

パスワードを確認するには、最初のパスワード ハッシュの作成に使用されたソルトが必要です。このソルトはcrypt()関数の出力文字列に含まれ、crypt はパスワード ハッシュからこのソルトを抽出できます。

PHP 5.5 からの新しいハッシュ関数password_hash()password_verify()...

$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);
$isPasswordCorrect = password_verify($password, $existingHashFromDb);

...ログインパスワードを検証する関数には、最初のパスワードのハッシュが必要です。次に、この文字列からソルトとコスト ファクターを抽出して、ログイン パスワードを同じパラメーターでハッシュします。

この新機能をお勧めします。以前のバージョン用の互換パックがあります。

于 2013-03-02T17:54:06.717 に答える