PHPで安全なパスワードハッシュを生成する方法
パスワードを安全に管理するためには、ソルトとストレッチングを用いてハッシュ値(暗号学的ハッシュ関数)としてデータベースに保存しておく必要があります。
このソルトとストレッチングを実施してハッシュ値を生成してくれるパスワードハッシュアルゴリズムには、「bcrypt」などが存在します。
そして、PHPには「password_hash」というパスワードハッシュを生成する関数が用意されています。
本記事では「password_hash」関数を利用した安全なパスワードハッシュを生成する方法を紹介しています。
スポンサーリンク
password_hash関数
password_hash関数を利用することで、安全なパスワードハッシュを生成できます。ソルトはオプションで指定することもできますが、ソルトを省略すれば、安全なソルトをこの関数が自動的に生成してくれます。
password_hash関数の引数は次の通りです。戻り値はハッシュ値の文字列が返却されます。
引数 | 型 | 説明 |
第一引数 | string | パスワードの文字列 |
第二引数 | int | 使用するハッシュアルゴリズム |
第三引数 | array | 任意のオプション(ソルトとアルゴリズムのコスト) |
ハッシュアルゴリズムの指定
第二引数のハッシュアルゴリズムは次の4パターンから指定します。
ハッシュアルゴリズム | 説明 |
PASSWORD_DEFAULT | bcryptアルゴリズムを使用。(PHP 5.5.0 の時点でのデフォルト)。新しくてより強力なアルゴリズムが PHP に追加されれば、 この定数もそれにあわせて変わっていく。 |
PASSWORD_BCRYPT | bcryptアルゴリズムを使用。 |
PASSWORD_ARGON2I | Argon2i ハッシュアルゴリズムを使用。 |
PASSWORD_ARGON2ID | Argon2id ハッシュアルゴリズムを使用。 |
ハッシュアルゴリズムを指定する実装例と実行結果は次の通りです。
【実装例】
$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 'パスワードは一致しない';
}
【実行結果】
パスワードは一致