web-dev-qa-db-ja.com

PHP 5.5のpassword_hashおよびpassword_verify関数を使用する

ユーザーのパスワードを保存したい場合、これはPHP 5.5のpassword_hash()関数(またはPHP 5.3.7のこのバージョンで行う正しい方法でしょうか) +: https://github.com/ircmaxell/password_compat )?

$options = array("cost" => 10, "salt" => uniqid());
$hash = password_hash($password, PASSWORD_BCRYPT, $options);

その後、私はやります:

mysql_query("INSERT INTO users(username,password, salt) VALUES($username, $hash, " . $options['salt']);

データベースに挿入します。

その後、確認するには:

$row = mysql_fetch_assoc(mysql_query("SELECT salt FROM users WHERE id=$userid"));
$salt = $row["salt"];
$hash = password_hash($password, PASSWORD_BCRYPT, array("cost" => 10, "salt" => $salt));

if (password_verify($password, $hash) {
    // Verified
}
32
Doug Smith

ここでは、データベースステートメントに関する問題を無視して、password_hashに関する質問に答えます。

要するに、いいえ、それはあなたがそれを行う方法ではありません。 saltのみを保存するのではなく、ハッシュとsaltの両方を保存し、両方を使用してパスワードを確認する必要があります。 password_hashは両方を含む文字列を返します。

password_hash関数は、ハッシュとソルトの両方を含む文字列を返します。そう:

$hashAndSalt = password_hash($password, PASSWORD_BCRYPT);
// Insert $hashAndSalt into database against user

その後、確認するには:

// Fetch hash+salt from database, place in $hashAndSalt variable
// and then to verify $password:
if (password_verify($password, $hashAndSalt)) {
   // Verified
}

さらに、コメントが示唆しているように、セキュリティに興味がある場合は、mysqli(PHP5.5ではext/mysqlは非推奨)、およびSQLインジェクションに関するこの記事を参照してください。- http://php.net/manual/en/security.database.sql-injection.php

59
Pete

独自のソルトを使用することはお勧めできません。PHP 7、 その使用は非推奨です 。現在、password_hashこれらの考えを共有しました(リンク切れ)

一つのことは私にとって非常に明確になりました:塩のオプションは危険です。私はまだまともな塩のオプションの単一の使用法を見ていません。すべての使用は、悪い(mt_Rand()出力を渡す)から危険な(静的な文字列)から非常識な(パスワードを独自のソルトとして渡す)範囲です。

私は、ユーザーがソルトを指定できるようにするべきではないと結論付けました。

彼は このコメントをSO chat で作成しました)==自分のソルトを渡すのがどれほど悪いか注意してください

11
Machavity

Php.netからこれに注意してください

警告

Saltオプションは、PHP 7.0.0の時点で非推奨になりました。デフォルトで生成されるsaltを使用することをお勧めします。

結論?塩オプションは忘れてください。

これで十分ですpassword_hash('password', PASSWORD_DEFAULT) *(または_BCRYPT)

7
Spooky

独自のソルトを入力したり、ソルトを空のままにしたりしないでください。関数は適切なランダムソルトを生成します。

関数によって返された文字列全体をデータベース(またはファイルまたは使用するもの)に挿入します。含まれているのは、アルゴリズムのID、コスト、ソルト(22文字)、およびハッシュパスワードです。

Password_verify()を使用するには、文字列全体が必要です。ソルトはランダムであり、(ハッシュ化されたパスワードを使用して)間違った手に落ちることを害しません。これにより、生成済みのパスワードとハッシュのリストであるレディセットを使用できなくなります(または非常に困難です)。

コストパラメータの追加を検討する必要があります。デフォルト(省略した場合)is 1-より高い場合、関数はハッシュをより長く計算します。コストを1増やすと、ハッシュの生成に2倍の時間が必要になります(したがって、パスワードを破るのにかかる時間が長くなります)

$hash = password_hash($password, PASSWORD_BCRYPT, array("cost" => 10));

サーバーの速度チェックに基づいてこのパラメーターを設定する必要があります。関数は100ミリ秒以上実行することをお勧めします(250ミリ秒にすることを好む人もいます)。通常、コスト= 10または11が適切な選択です(2015年)。

セキュリティを強化するには、パスワードに長い(50〜60文字が適切な)秘密の文字列を追加することができます。 password_hash()またはpassword_verify()を使用する前に。

$secret_string = 'asCaahC72D2bywdu@#$@#$234';
$password  = trim($_POST['user_password']) . $secret_string;
// here use password_* function

注意PASSWORD_BCRYPTをalgoパラメーターに使用すると、パスワードパラメーターが最大長の72文字に切り捨てられます。

$ passwordが72文字より長くなり、73または90文字のハッシュを変更または追加しても、ハッシュは変更されません。オプションで、$ secret_stringの貼り付けは最後に行う必要があります(ユーザーのパスワードの前ではなく、ユーザーのパスワードの後)。

5
Adam