password_hash
パスワードハッシュを作る
説明
string password_hash(#[\SensitiveParameter]string $password
, stringintnull $algo
, array $options
= [])
現在、以下のアルゴリズムに対応しています。
-
PASSWORD_DEFAULT
- bcrypt アルゴリズムを使います (PHP 5.5.0 の時点でのデフォルトです)。
新しくてより強力なアルゴリズムが PHP に追加されれば、
この定数もそれにあわせて変わっていきます。
そのため、これを指定したときの結果の長さは、変わる可能性があります。
したがって、結果をデータベースに格納するときにはカラム幅を
60 文字以上にできるようなカラムを使うことをお勧めします
(255 文字くらいが適切でしょう)。
-
PASSWORD_BCRYPT
- CRYPT_BLOWFISH
アルゴリズムを使ってハッシュを作ります。これは標準の crypt
互換のハッシュで、識別子 "$2y$" を使った場合の結果を作ります。
その結果は、常に 60 文字の文字列になります。失敗した場合に false
を返します。
-
PASSWORD_ARGON2I
- Argon2i ハッシュアルゴリズムを使って
ハッシュを作ります。このアルゴリズムは、
PHP が Argon2 のサポートを有効にしてコンパイルした場合のみ利用できます。
-
PASSWORD_ARGON2ID
- Argon2id ハッシュアルゴリズムを使って
ハッシュを作ります。このアルゴリズムは、
PHP が Argon2 のサポートを有効にしてコンパイルした場合のみ利用できます。
PASSWORD_BCRYPT
がサポートするオプション:
-
salt
(string) - パスワードのハッシュに使うソルトを手動で設定します。
これは、自動生成されたソルトを上書きすることに注意しましょう。
省略した場合は、パスワードをハッシュするたびに password_hash
がランダムなソルトを自動生成します。これは意図したとおりの操作モードです。
警告
このソルト・オプションは 非推奨になっています。
このオプションは指定せずに、デフォルトで生成されるソルトを使うことを推奨します。
PHP 8.0.0 以降は、この値を明示的に指定しても無視されます。
-
cost
(int) - 利用するアルゴリズムのコストを表します。
値の例については crypt のページを参照ください。
省略した場合のデフォルトは 10
です。この値でもかまいませんが、
ハードウェアの性能が許すならもう少し高くすることもできます。
PASSWORD_ARGON2I
と
PASSWORD_ARGON2ID
が
サポートするオプション
-
memory_cost
(int) - Argon2 ハッシュを計算するのに
使われるメモリの最大値(キロバイト単位)。
デフォルトは PASSWORD_ARGON2_DEFAULT_MEMORY_COST
です。
-
time_cost
(int) - Argon2 ハッシュを計算するのに
使って良い時間の最大値。
デフォルトは PASSWORD_ARGON2_DEFAULT_TIME_COST
です。
-
threads
(int) - Argon2 ハッシュを計算するのに使う
スレッド数。
デフォルトは PASSWORD_ARGON2_DEFAULT_THREADS
です。
警告
PHP が libargon2 を使う場合にのみ利用可能です。
libsodium の実装では利用できません。
パラメータ
-
password
-
ユーザーのパスワード。
警告
PASSWORD_BCRYPT
をアルゴリズムに指定すると、
password
が最大 72 バイトまでに切り詰められます。
-
algo
-
パスワードのハッシュに使うアルゴリズムを表す
パスワードアルゴリズム定数。
-
options
-
オプションを含む連想配列。各アルゴリズムがサポートするオプションについては、
パスワードアルゴリズム定数
のページを参照ください。
省略した場合は、ランダムな salt を生成してデフォルトのコストを使います。
戻り値
ハッシュしたパスワードを返します。
使ったアルゴリズムやコスト、そしてソルトもハッシュの一部として返されます。
つまり、ハッシュを検証するために必要な情報は、すべてそこに含まれているということです。
そのため、password_verify でハッシュを検証するときに、
ソルトやアルゴリズムの情報を別に保存する必要はありません。
例
例1 password_hash の例
<?php
/**
* デフォルトのアルゴリズムを使ってパスワードをハッシュします。
* 現時点でのデフォルトは BCRYPT で、その結果は 60 文字になります。
*
* デフォルトは、今後変わる可能性があることに注意しましょう。結果が
* 60 文字以上になっても対応できるようにしておきましょう (255 あたりが適切です)
*/
echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT);
?>
$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a
例2 password_hash で、コストを手動で設定する例
<?php
/**
* この例では、BCRYPT のコストをデフォルトより上げて、12 にします。
* また、アルゴリズムを BCRYPT に変えたことにも注目しましょう。結果は常に 60 文字になります。
*/
$options = [
'cost' => 12,
];
echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options);
?>
$2y$12$QjSH496pcT5CEbzjD/vtVeH03tfHKFy36d4J0Ltp3lRtee9HDxY3K
例3 password_hash で、適切なコストを探す例
<?php
/**
* このコードは、サーバーをベンチマークして、どの程度のコストに耐えられるかを判断します。
* サーバーに負荷をかけすぎない範囲で、できるだけ高めのコストを設定したいものです。
* 基準として 10 程度からはじめ、サーバーが十分に高速なら、できるだけ上げていきましょう。
* 以下のコードでは、ストレッチングの時間を 350 ミリ秒以内にすることを狙っています。
* 対話形式のログインを扱う際の許容時間としては、このあたりが適切でしょう。
*/
$timeTarget = 0.350; // 350 ミリ秒
$cost = 10;
do {
$cost++;
$start = microtime(true);
password_hash("test", PASSWORD_BCRYPT, ["cost" => $cost]);
$end = microtime(true);
} while (($end - $start) < $timeTarget);
echo "Appropriate Cost Found: " . $cost;
?>
Appropriate Cost Found: 12
例4 Argon2i を使った password_hash の例
<?php
echo 'Argon2i hash: ' . password_hash('rasmuslerdorf', PASSWORD_ARGON2I);
?>
Argon2i hash: $argon2i$v=19$m=1024,t=2,p=2$YzJBSzV4TUhkMzc3d3laeg$zqU/1IN0/AogfP4cmSJI1vc8lpXRW9/S0sYY2i2jHT0
注意
警告
この関数で使うソルトを自前で設定するのはお勧めしません。
ソルトを省略すれば、安全なソルトをこの関数が自動的に作ってくれます。
先述のとおり、PHP 7.0 で salt
オプションを指定すると、
非推奨の警告が発生します。ソルトを手動で設定する仕組みは、PHP 8.0 で削除されました。
注意:
実際にサーバー上でこの関数をテストして、コストパラメータの適切な設定値を調整することをお勧めします。
対話型のシステムなら、関数の実行時間が 350 ミリ秒くらいに収まるくらいが適切です。
先ほどの例のスクリプトは、自分のハードウェア上での適切なコストを判断するための助けとなるでしょう。
注意:
この関数がサポートするアルゴリズムの更新 (あるいはデフォルトのアルゴリズムの変更)
は、必ず次の手順にのっとって行われます。
-
新しく追加されたアルゴリズムがデフォルトになるまでには、
少なくとも一度は PHP のフルリリースを経ること。
つまり、たとえば、新しいアルゴリズムが 7.5.5 で追加されたとすると、
そのアルゴリズムがデフォルトになるのは早くても 7.7 以降ということになります
(7.6 は、最初のフルリリースだからです)。
しかし、もし別のアルゴリズムが 7.6.0 で追加されたとすると、
そのアルゴリズムも 7.7.0 の時点でデフォルトになる資格を得ます。
-
デフォルトを変更できるのはフルリリース (7.3.0 や 8.0.0 など)
のときだけで、リビジョンリリースでは変更できない。
唯一の例外は、現在のデフォルトにセキュリティ上の致命的な欠陥が発覚した場合の緊急リリースです。
参考
- password_verify
- password_needs_rehash
- crypt
- sodium_crypto_pwhash_str