関数・クラス解説

password_hash

version:PHP 5 >= 5.5.0, PHP 7 (公式)

パスワードハッシュを作る

公式リファレンス

書式

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() でハッシュを検証するときに、 ソルトやアルゴリズムの情報を別に保存する必要はありません。

注意

警告 この関数で使うソルトを自前で設定するのはお勧めしません。 ソルトを省略すれば、安全なソルトをこの関数が自動的に作ってくれます。 先述のとおり、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 など) のときだけで、リビジョンリリースでは変更できない。 唯一の例外は、現在のデフォルトにセキュリティ上の致命的な欠陥が発覚した場合の緊急リリースです。
警告 このソルト・オプションは、PHP 7.0.0 で非推奨になりました。 このオプションは指定せずに、デフォルトで生成されるソルトを使うことを推奨します。

更新履歴

バージョン 説明
7.4.0 algo パラメータは string を期待するようになりました。 しかし、後方互換性のために int も未だ受け入れています。
7.3.0 PASSWORD_ARGON2ID を使った、 Argon2id パスワードのサポートが追加されました。
7.2.0 PASSWORD_ARGON2I を使った、 Argon2i パスワードのサポートが追加されました。

サンプル

例1 password_hash() の例

/**  * デフォルトのアルゴリズムを使ってパスワードをハッシュします。  * 現時点でのデフォルトは BCRYPT で、その結果は 60 文字になります。  *  * デフォルトは、今後変わる可能性があることに注意しましょう。結果が  * 60 文字以上になっても対応できるようにしておきましょう (255 あたりが適切です)  */ echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT);

上の例の出力は、たとえば以下のようになります。

$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a

例2 password_hash() で、コストを手動で設定する例

/**  * この例では、BCRYPT のコストをデフォルトより上げて、12 にします。  * また、アルゴリズムを BCRYPT に変えたことにも注目しましょう。結果は常に 60 文字になります。  */ $options = [     'cost' => 12, ]; echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options);

上の例の出力は、たとえば以下のようになります。

$2y$12$QjSH496pcT5CEbzjD/vtVeH03tfHKFy36d4J0Ltp3lRtee9HDxY3K

例3 password_hash() で、適切なコストを探す例

/**  * このコードは、サーバーをベンチマークして、どの程度のコストに耐えられるかを判断します。  * サーバーに負荷をかけすぎない範囲で、できるだけ高めのコストを設定したいものです。  * 基準として 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() の例

echo 'Argon2i hash: ' . password_hash('rasmuslerdorf', PASSWORD_ARGON2I);

上の例の出力は、たとえば以下のようになります。

Argon2i hash: $argon2i$v=19$m=1024,t=2,p=2$YzJBSzV4TUhkMzc3d3laeg$zqU/1IN0/AogfP4cmSJI1vc8lpXRW9/S0sYY2i2jHT0

参考

  • password_verify() - パスワードがハッシュにマッチするかどうかを調べる
  • crypt() - 文字列の一方向のハッシュ化を行う
  • » ユーザーランドでの実装
  • sodium_crypto_pwhash_str() - Get an ASCII-encoded hash
  • ワード検索


    ※入力キーワードが、関数名・説明文・タグに含まれるものを検索

    関数名アルファベット別

    A B C D E F G H I J
    K L M N O P Q R S T
    U V W X Y Z _

    最終更新一覧

    stristr
     大文字小文字を区別せず文字列を検索し、ヒット箇所以降(あるいは以前)の文字列を返却

    stripslashes
     バックスラッシュでエスケープされた文字列から、バックスラッシュを取り除く

    stripos
     大文字小文字を区別せずに文字列が最初に現れる位置を取得する

    stripcslashes
     addcslashes() でクォートされた文字列をアンクォートする

    strip_tags
     文字列から HTML と PHP のタグを除去して返却

    strcspn
     指定した文字が最初に現れる位置を調べる

    strcoll
     ロケールに基づいて2つの文字列を比較し同じか(あるいは大小)を判定する

    strcmp
     2つの文字列を比較し同じか(あるいは大小)を判定する

    strchr
     strstr() のエイリアス

    strcasecmp
     2つの文字列を比較(大文字小文字を区別せず同じとみなす)

    カテゴリー一覧

    PHP の振る舞いの変更
    音声フォーマットの操作
    認証サービス
    コマンドライン関連
    圧縮およびアーカイブ
    暗号
    データベース関連
    日付および時刻関連
    ファイルシステム
    自然言語および文字エンコーディング
    画像処理および作成
    メール関連
    数学
    テキスト以外の MIME 型
    プロセス制御
    その他の基本モジュール
    その他のサービス
    検索エンジン用の拡張モジュール
    サーバー固有のモジュール
    セッション関連
    テキスト処理
    変数・データ型関連
    ウェブサービス
    Windows 用のモジュール
    XML 操作
    GUI用の拡張モジュール