password_hash
(PHP 5 >= 5.5.0, PHP 7)
password_hash — パスワードハッシュを作る
説明
password_hash
( string $password
, mixed $algo
[, array $options
] ) : string|false
password_hash() は、強力な一方向ハッシュアルゴリズムを使って 新しいパスワードハッシュを作ります。 password_hash() は crypt() と互換性があるので、 crypt() が作ったパスワードハッシュは password_hash() でも使えます。
現在、以下のアルゴリズムに対応しています。
-
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 7.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
です。
パラメータ
password
ユーザーのパスワード。
警告
PASSWORD_BCRYPT
をアルゴリズムに指定すると、password
が最大 72 文字までに切り詰められます。algo
パスワードのハッシュに使うアルゴリズムを表す パスワードアルゴリズム定数。
options
オプションを含む連想配列。各アルゴリズムがサポートするオプションについては、 パスワードアルゴリズム定数 のページを参照ください。
省略した場合は、ランダムな salt を生成してデフォルトのコストを使います。
返り値
ハッシュしたパスワードを返します。失敗した場合に false
を返します。
使ったアルゴリズムやコスト、そしてソルトもハッシュの一部として返されます。 つまり、ハッシュを検証するために必要な情報は、すべてそこに含まれているということです。 そのため、password_verify() でハッシュを検証するときに、 ソルトやアルゴリズムの情報を別に保存する必要はありません。
変更履歴
バージョン | 説明 |
---|---|
7.4.0 | algo パラメータは string を期待するようになりました。
しかし、後方互換性のために int も未だ受け入れています。 |
7.3.0 | PASSWORD_ARGON2ID を使った、
Argon2id パスワードのサポートが追加されました。 |
7.2.0 | PASSWORD_ARGON2I を使った、
Argon2i パスワードのサポートが追加されました。 |
例
例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/** * このコードは、サーバーをベンチマークして、どの程度のコストに耐えられるかを判断します。 * サーバーに負荷をかけすぎない範囲で、できるだけ高めのコストを設定したいものです。 * 基準として 8 から 10 程度からはじめ、サーバーが十分に高速なら、できるだけ上げていきましょう。 * 以下のコードでは、ストレッチングの時間を 50 ミリ秒以内にすることを狙っています。 * 対話形式のログインを扱う際の許容時間としては、このあたりが妥当なところでしょう。 */$timeTarget = 0.05; // 50 ミリ秒$cost = 8;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: 10
例4 Argon2i を使った password_hash() の例
<?phpecho '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
オプションを指定すると、
非推奨の警告が発生します。ソルトを手動で設定する仕組みは、将来のリリースで廃止されるかもしれません。
注意:
実際にサーバー上でこの関数をテストして、コストパラメータの適切な設定値を調整することをお勧めします。 対話型のシステムなら、関数の実行時間が 100 ミリ秒くらいに収まるくらいが適切です。 先ほどの例のスクリプトは、自分のハードウェア上での適切なコストを判断するための助けとなるでしょう。
注意:
この関数がサポートするアルゴリズムの更新 (あるいはデフォルトのアルゴリズムの変更) は、必ず次の手順にのっとって行われます。
- 新しく追加されたアルゴリズムがデフォルトになるまでには、 少なくとも一度は PHP のフルリリースを経ること。 つまり、たとえば、新しいアルゴリズムが 7.5.5 で追加されたとすると、 そのアルゴリズムがデフォルトになるのは早くても 7.7 以降ということになります (7.6 は、最初のフルリリースだからです)。 しかし、もし別のアルゴリズムが 7.6.0 で追加されたとすると、 そのアルゴリズムも 7.7.0 の時点でデフォルトになる資格を得ます。
- デフォルトを変更できるのはフルリリース (7.3.0 や 8.0.0 など) のときだけで、リビジョンリリースでは変更できない。 唯一の例外は、現在のデフォルトにセキュリティ上の致命的な欠陥が発覚した場合の緊急リリースです。
参考
- password_verify() - パスワードがハッシュにマッチするかどうかを調べる
- crypt() - 文字列の一方向のハッシュ化を行う
- » ユーザーランドでの実装
- sodium_crypto_pwhash_str() - Get an ASCII-encoded hash