古い投稿を変更しました。 crypt()関数を試し、password_hash()およびpassword_verify()を使用して、データベースからの暗号化されたパスワードを確認しようとしましたが、呼び出しごとに、password_hash()関数が異なる暗号化文字列を再調整し、password_verify()がそれに一致しません。
これが私がこれをしている方法です。
//please ignore the syntax error if any
$data = '11';
$dbpass = password_hash($data, PASSWORD_BCRYPT);
echo $dbpass; // displays the random strings on each page refresh.
パスワードがデータベースに保存されると、ログインプロセス中に一致しなくなります。以下は私の実際の機能です。
private function process_data($password){
$password = __STR.$password.__STR;
return password_hash($password, PASSWORD_BCRYPT);
}
private function processed($login_password, $dbpassword){
$login_password = __STR.$login_password.__STR;
return password_verify($login_password, $dbpassword);
}
パスワードのハッシュ文字列を作成するための各関数呼び出しで、関数は次回は異なる文字列を返します。
では、これを1つずつ見ていきましょう。
まず、暗号化ではなく、ハッシュです。暗号化は双方向であり、ハッシュは一方向です。ハッシュしたい。暗号化したくありません。はい、用語は重要です。正しい用語を使用してください。
次に、_password_hash
_への各呼び出しはsupposedであり、異なるハッシュを返します。それは強いランダムな塩を生成しているからです。これが設計方法であり、実際に使用する方法です。
さらに、DO NOTは、パスワードの前後に___STR
_を追加するという「コショウ」のことをしません。あなたは何もしていないが、ユーザーのパスワードを弱める可能性がある(これは良くない)。それが悪い考えである理由に関する詳細情報が必要な場合: この回答を読んでください 。
続けて、crypt
を直接使用しないことを強くお勧めします。実際、驚くほど簡単に台無しにして、非常に弱いハッシュを生成することができます。これが、_password_*
_ apiが設計された理由です。 crypt
は低レベルのライブラリであり、コードで高レベルのライブラリを使用する必要があります。 bcryptを台無しにする方法の詳細については、私のブログをチェックしてください: Bcryptを台無しにする7つの方法 。
Password APIは、シンプルなワンストップショップとして設計されました。それが機能しない場合は、次のことを確認してください。
PHP> = 5.5.0を使用していますか?またはPHP> = 5.3.7 with password_compat を使用していますか?
データベースの列の幅は十分ですか?
少なくとも60文字の長さである必要があります。
関数の結果がbool(false)
ではなく文字列であることを確認していますか?
内部エラーがある場合は、_password_hash
_から非文字列を返します。
エラーが発生していますか?
_error_reporting
_を最大設定にオンにして(すべてをキャッチするには_-1
_をお勧めします)、コードがエラーをスローしていないことを確認しましたか?
正しく使用していますか?
_function saveUser($username, $password) {
$hash = password_hash($password, PASSWORD_BCRYPT);
// save $username and $hash to db
}
function login($username, $password) {
// fetch $hash from db
return password_verify($password, $hash);
}
_
それぞれを1回だけ呼び出す必要があることに注意してください。
PHP <5.3.7 with password_compat ?を使用していますか?そうであれば、これが問題です。サポートされていないバージョンのPHPで互換性ライブラリを使用しています。動作させる(特定のRedHatディストリビューションが必要な修正をバックポートしている)が、サポートされていないバージョンを使用している。妥当なリリースにアップグレードしてください。
他のすべてが失敗した場合は、このコードを実行して出力を報告してみてください。
_$hash = '$2y$04$usesomesillystringfore7hnbRJHxXVLeakoG8K30oukPsA.ztMG';
$test = crypt("password", $hash);
$pass = $test == $hash;
echo "Test for functionality of compat library: " . ($pass ? "Pass" : "Fail");
echo "\n";
_
それがFail
を返す場合は、サポートされていないバージョンのPHPを実行しているため、アップグレードする必要があります。passが返される場合は、ロジックのどこかにエラーがあります(ライブラリは正常に機能しています)。 )。
パスワードを保存する最良の方法は、PHPの関数 password_hash() を使用することです。パスワードごとに暗号で安全なソルトを自動的に生成し、結果の60文字の文字列に含めます。塩の心配は一切ありません!
_// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);
// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($password, $existingHashFromDb);
_
独自のスキームは非常に弱く、最初にパスワードハッシュを生成するには速すぎるMD5を使用し、次に静的ソルトを使用します。これはソルトの目的を無効にします。 パスワードを安全に保存する についての私のチュートリアルを見てみたいと思うかもしれません。
更新された質問に答えるために編集:
パスワードに___STR
_を追加する必要はありません(ペッパーを追加したい場合は、より良い方法があります)が、サンプル関数は実際に機能するはずです。 password_hash()
の戻り値は、ランダムなソルトのために毎回異なります。これは正しいです。関数password_verify()
は検証のためにこのソルトを抽出できます。あなたの場合、データベースフィールドがおそらく問題です。 60文字の文字列を保持できることを確認してください。