PHP

【bcrypt】PHPで安全なパスワードハッシュを生成する方法

2020年5月6日

PHPで安全なパスワードハッシュを生成する方法

パスワードを安全に管理するためには、ソルトストレッチングを用いてハッシュ値(暗号学的ハッシュ関数)としてデータベースに保存しておく必要があります。

このソルトとストレッチングを実施してハッシュ値を生成してくれるパスワードハッシュアルゴリズムには、「bcrypt」などが存在します。

そして、PHPには「password_hash」というパスワードハッシュを生成する関数が用意されています。

本記事では「password_hash」関数を利用した安全なパスワードハッシュを生成する方法を紹介しています。

ソルトやストレッチングについての詳細は次の関連記事をご覧ください。

スポンサーリンク

password_hash関数

password_hash関数を利用することで、安全なパスワードハッシュを生成できます。ソルトはオプションで指定することもできますが、ソルトを省略すれば、安全なソルトをこの関数が自動的に生成してくれます。

password_hash関数の引数は次の通りです。戻り値はハッシュ値の文字列が返却されます。

引数説明
第一引数stringパスワードの文字列
第二引数int使用するハッシュアルゴリズム
第三引数array任意のオプション(ソルトとアルゴリズムのコスト)

ハッシュアルゴリズムの指定

第二引数のハッシュアルゴリズムは次の4パターンから指定します。

ハッシュアルゴリズム説明
PASSWORD_DEFAULTbcryptアルゴリズムを使用。(PHP 5.5.0 の時点でのデフォルト)。新しくてより強力なアルゴリズムが PHP に追加されれば、 この定数もそれにあわせて変わっていく。
PASSWORD_BCRYPTbcryptアルゴリズムを使用。
PASSWORD_ARGON2IArgon2i ハッシュアルゴリズムを使用。
PASSWORD_ARGON2IDArgon2id ハッシュアルゴリズムを使用。

ハッシュアルゴリズムを指定する実装例と実行結果は次の通りです。

【実装例】

$password = "password12345";
echo "PASSWORD_DEFAULT:".password_hash($password, PASSWORD_DEFAULT). "<br>";
echo "PASSWORD_BCRYPT:".password_hash($password, PASSWORD_BCRYPT). "<br>";
echo "PASSWORD_ARGON2I:".password_hash($password, PASSWORD_ARGON2I). "<br>";
echo "PASSWORD_ARGON2ID:".password_hash($password, PASSWORD_ARGON2ID). "<br>";

【実行結果】

PASSWORD_DEFAULT:$2y$10$hlvC.9Z0eV.LglGQkbHOKefezCBJBIQmqCO3Q/.6orWxACQ8mr9Eq
PASSWORD_BCRYPT:$2y$10$.MRZbsnrxS2/rUwgLd4qYeEM2LjXyyLA8ZzL9rN6mN2nNxvhWTIju
PASSWORD_ARGON2I:$argon2i$v=19$m=65536,t=4,p=1$MTY3NVF5RjE1ODRBNUlWcQ$o4toYM+aJPYby8ke49LzrOoZhpFC6zJcB2rLcRu0wwg
PASSWORD_ARGON2ID:$argon2id$v=19$m=65536,t=4,p=1$L1hFLzZKRjVuazk5Y3hhcg$u0RCdmmL9fyVh0BB4p15lV+8v/0To5080gwI3M7S9yQ

オプションの指定

ハッシュアルゴリズム「PASSWORD_BCRYPT」がサポートするオプションは次の通りです。

オプション名説明
saltパスワードのハッシュに使うソルトを手動で設定。PHP 7.0.0 から非推奨のオプションであり、このオプションは指定せずに、デフォルトで生成されるソルトを使うことを推奨している。
cost利用するアルゴリズムのコスト(ストレッチング回数)を示す。

手動のソルトを指定

オプションで「ソルト」を指定する実装例と実行結果は次の通りです。

【実装例】

$password = "password12345";
$options = [
    'salt' => "mOqouj.7VRXjNci58C1xKu",
];
echo password_hash($password, PASSWORD_BCRYPT, $options);

【実行結果】

$2y$10$mOqouj.7VRXjNci58C1xKuc.pI8no9Q0VNk2yG0DsX7r7BoBujhXC

スポンサーリンク

アルゴリズムのコストを指定(ストレッチング回数)

オプションで「アルゴリズムのコスト」を指定する実装例と実行結果は次の通りです。

【実装例】

$password = "password12345";
$options = [
    'cost' => 11,
];
echo password_hash($password, PASSWORD_BCRYPT, $options);

【実行結果】

$2y$11$q2uzpPrLlVLJmRQQuvl9G.RJOJbSHR.Y2jAwVUgZ9./ooXmOmdihm

手動のソルトとアルゴリズムのコスト(ストレッチング回数)を指定

オプションで「ソルト」と「アルゴリズムのコスト」を指定する実装例と実行結果は次の通りです。

【実装例】

$password = "password12345";
$options = [
    'cost' => 12,
    'salt' => "mOqouj.7VRXjNci58C1xKu",
];
echo password_hash($password, PASSWORD_BCRYPT, $options);

【実行結果】

$2y$12$mOqouj.7VRXjNci58C1xKuZHdLn7zZd8z7A71CPzHQ1wmP.FXVdQu

password_verify関数

password_verify関数は、引数に指定した「平文」と「パスワードハッシュ」が一致するかを確認するための関数です。

password_verify ( string $password , string $hash ) : bool

第一引数に平文のパスワード、第二引数にpassword_hash関数が作ったハッシュ値を指定します。

「password_hash」関数と「password_verify」関数を使った実装例は次の通りです。

【実装例】

$password = "password12345";
$hashed = password_hash($password, PASSWORD_DEFAULT);
if(password_verify($password, $hashed)) {
    echo 'パスワードは一致';
} else {
    echo 'パスワードは一致しない';
}

【実行結果】

パスワードは一致

helpful