【PHP8.x】password_verify()関数の使い方
password_verify関数の使い方について、初心者にもわかりやすく解説します。
基本的な使い方
password_verify関数は、ユーザーが入力したパスワードと、データベースなどに安全に保存されているハッシュ化されたパスワードが一致するかどうかを検証するために使用する関数です。この関数は、主にログイン認証の際に、ユーザーが入力した生のパスワードと、以前にpassword_hash()関数で生成されて保存されたハッシュ値とを比較し、その妥当性を判断します。
第一引数にはユーザーがフォームなどから入力した平文のパスワードを、第二引数にはあらかじめpassword_hash()関数によって生成され、データベースなどに保存されているハッシュ化されたパスワードを指定します。パスワードが一致した場合はブール値のtrueを返し、一致しなかった場合はfalseを返します。
この関数の大きな特徴は、単なる文字列比較ではなく、セキュリティを考慮した安全な方法で検証を行う点です。具体的には、タイミング攻撃などのサイドチャネル攻撃を防ぐための仕組みが内部に組み込まれており、パスワードを安全に取り扱う上で非常に推奨される方法です。パスワードを直接平文で保存することなく、常にハッシュ化された形式で管理し、検証時にこのpassword_verify()関数を使用することで、堅牢な認証システムを構築できます。PHP 8環境において、セキュアなパスワード処理を実現するための基盤となる重要な関数の一つです。
構文(syntax)
1<?php 2$userEnteredPassword = 'mySecurePassword123'; 3$storedHashedPassword = '$2y$10$s.a.l.t.y.h.a.s.h.v.a.l.u.e.f.r.o.m.d.a.t.a.b.a.s.e.h.e.r.e.'; 4 5$isPasswordCorrect = password_verify($userEnteredPassword, $storedHashedPassword); 6?>
引数(parameters)
string $password, string $hash
- string $password: 検証したい平文のパスワード
- string $hash: 検証に使用するハッシュ化されたパスワード
戻り値(return)
bool
指定されたパスワードが、指定されたハッシュ値と一致するかどうかを真偽値(bool)で返します。一致する場合は true、一致しない場合は false を返します。
サンプルコード
password_verifyがfalseを返す原因と対策
1<?php 2 3/** 4 * password_verify() 関数の動作をデモンストレーションする関数です。 5 * 特に「password_verify() が常に false を返す」という問題の 6 * 一般的な原因について説明します。 7 */ 8function demonstratePasswordVerification(): void 9{ 10 echo "<h2>password_verify() 関数のデモンストレーション</h2>"; 11 12 // 1. パスワードのハッシュ化(正しいハッシュの生成) 13 // password_hash() は、安全なパスワードハッシュを生成するために推奨される関数です。 14 // 同じ平文パスワードでも、毎回異なるハッシュが生成されます。 15 $plainPassword = 'MySecurePassword123!'; 16 $hashedPassword = password_hash($plainPassword, PASSWORD_BCRYPT); 17 18 echo "<h3>シナリオ 1: 正しいパスワードと正しいハッシュでの検証 (成功例)</h3>"; 19 echo "平文のパスワード: '" . $plainPassword . "'<br>"; 20 echo "生成されたハッシュ: '" . $hashedPassword . "'<br>"; 21 22 // 正しいパスワードで検証を試みる 23 if (password_verify($plainPassword, $hashedPassword)) { 24 echo "<b>結果: 検証成功 (true)</b> - パスワードが一致しました。<br>"; 25 } else { 26 echo "<b>結果: 検証失敗 (false)</b> - この結果は通常、期待されません。<br>"; 27 } 28 echo "<hr>"; 29 30 // 2. 誤ったパスワードでの検証 (false を返す典型例) 31 $wrongPassword = 'WrongPassword456!'; 32 echo "<h3>シナリオ 2: 間違ったパスワードでの検証 (失敗例)</h3>"; 33 echo "試行パスワード: '" . $wrongPassword . "'<br>"; 34 echo "検証対象ハッシュ: '" . $hashedPassword . "'<br>"; 35 36 // 間違ったパスワードで検証を試みる 37 if (password_verify($wrongPassword, $hashedPassword)) { 38 echo "<b>結果: 検証成功 (true)</b> - この結果は通常、期待されません。<br>"; 39 } else { 40 echo "<b>結果: 検証失敗 (false)</b> - パスワードが一致しませんでした。<br>"; 41 } 42 echo "<hr>"; 43 44 // 3. password_hash() 以外で生成されたハッシュでの検証 (「常に false を返す」原因の一つ) 45 // password_verify() は、password_hash() で生成された特定の形式のハッシュのみを認識します。 46 // md5() のような古い、または異なるハッシュアルゴリズムで生成された文字列を渡すと、 47 // 内容が一致していても常に false を返します。 48 $md5HashedPassword = md5($plainPassword); 49 echo "<h3>シナリオ 3: password_hash() 以外で生成されたハッシュでの検証 (「常に false を返す」主な原因)</h3>"; 50 echo "平文のパスワード: '" . $plainPassword . "'<br>"; 51 echo "MD5ハッシュ: '" . $md5HashedPassword . "' (これは password_hash() で生成されたものではありません)<br>"; 52 53 // MD5ハッシュで検証を試みる 54 if (password_verify($plainPassword, $md5HashedPassword)) { 55 echo "<b>結果: 検証成功 (true)</b> - <span style='color: red;'>この結果は絶対に起こりえません!</span><br>"; 56 } else { 57 echo "<b>結果: 検証失敗 (false)</b> - <br>"; 58 echo "<p><b>重要:</b> <code>password_verify()</code> は、<code>password_hash()</code> で生成されたハッシュ文字列のみを検証するように設計されています。<br> 59 それ以外のハッシュ(例: <code>md5()</code>, <code>sha1()</code> など)を渡すと、たとえ平文パスワードが正しくても<b>常に <code>false</code> を返します。</b><br> 60 これが「<code>password_verify()</code> が常に <code>false</code> を返す」という問題のよくある原因です。</p>"; 61 } 62 echo "<hr>"; 63 64 // 4. 不正な形式のハッシュ文字列での検証 (false を返すケース) 65 // 有効なハッシュ形式でない文字列を渡した場合も false を返します。 66 $invalidHashFormat = 'thisisnotavalidhashformatstring$'; 67 echo "<h3>シナリオ 4: 不正な形式のハッシュ文字列での検証</h3>"; 68 echo "平文のパスワード: '" . $plainPassword . "'<br>"; 69 echo "不正なハッシュ: '" . $invalidHashFormat . "'<br>"; 70 71 if (password_verify($plainPassword, $invalidHashFormat)) { 72 echo "<b>結果: 検証成功 (true)</b> - この結果は通常、期待されません。<br>"; 73 } else { 74 echo "<b>結果: 検証失敗 (false)</b> - ハッシュの形式が不正です。<br>"; 75 } 76 echo "<hr>"; 77} 78 79// 関数の実行 80demonstratePasswordVerification(); 81 82?>
PHPのpassword_verify関数は、ユーザーが入力した平文のパスワードが、データベースなどに保存されているハッシュ化されたパスワードと一致するかどうかを安全に検証するために使用されます。第一引数にはユーザーが入力した平文のパスワードを、第二引数には検証対象となるハッシュ化されたパスワード文字列を渡します。検証が成功し、パスワードが一致していればtrueを、一致しなければfalseを返します。
このサンプルコードでは、password_verify関数の基本的な動作と、特に「常にfalseを返す」という問題の原因を説明しています。まず、password_hash()関数で安全なパスワードハッシュを生成し、正しいパスワードで検証が成功する例を示します。次に、誤ったパスワードが与えられた場合にfalseが返される、期待通りの動作を紹介しています。
最も重要な点として、password_verify関数はpassword_hash()で生成された特定の形式のハッシュ文字列のみを検証するように設計されています。もしmd5()やsha1()といった他のハッシュ関数で生成された文字列を第二引数に渡すと、たとえ平文パスワードが正しくても、この関数は常にfalseを返します。また、有効なハッシュ形式ではない文字列を渡した場合も同様にfalseを返します。したがって、パスワードのハッシュ化と検証を行う際は、必ずpassword_hash()とpassword_verify()をセットで使用することが非常に重要です。
password_verify関数は、password_hash関数で作成されたハッシュ文字列のみを検証します。そのため、md5()やsha1()といった他の方法で生成されたハッシュを渡すと、平文パスワードが正しくても常にfalseを返します。これが「password_verify()が常にfalseを返す」という問題の主な原因です。また、パスワードが一致しない場合や、渡されたハッシュの形式が不正な場合もfalseが返ります。安全なパスワード認証を実現するためには、必ずpassword_hash()とpassword_verify()を組み合わせて使用してください。
PHP password_verify でパスワード検証する
1<?php 2 3/** 4 * password_verify 関数の使用例を示します。 5 * パスワードのハッシュ化(登録時を想定)と、その後の検証(ログイン時を想定)の一連の流れをシミュレートします。 6 * 7 * @param string $plainPassword 検証したい生パスワード 8 * @return void 9 */ 10function demonstratePasswordVerification(string $plainPassword): void 11{ 12 echo "--- 1. パスワードのハッシュ化(ユーザー登録時を想定) ---\n"; 13 // password_hash() は指定されたアルゴリズム(例: bcrypt)を使用してパスワードをハッシュ化します。 14 // PASSWORD_DEFAULT は現時点で推奨されるアルゴリズムを使用します。 15 $hashedPassword = password_hash($plainPassword, PASSWORD_DEFAULT); 16 17 if ($hashedPassword === false) { 18 echo "エラー: パスワードのハッシュ化に失敗しました。\n"; 19 return; 20 } 21 22 echo "生パスワード: " . $plainPassword . "\n"; 23 echo "ハッシュ化されたパスワード (DBに保存される値): " . $hashedPassword . "\n\n"; 24 25 echo "--- 2. パスワードの検証(ログイン時を想定) ---\n"; 26 27 // シナリオ1: ユーザーが正しいパスワードを入力した場合 28 $inputPasswordCorrect = $plainPassword; 29 echo "入力されたパスワード (正しい場合): " . $inputPasswordCorrect . "\n"; 30 31 // password_verify() は、生のパスワードとハッシュ化されたパスワードが一致するかを検証します。 32 if (password_verify($inputPasswordCorrect, $hashedPassword)) { 33 echo "結果: パスワードは一致しました。ログイン成功。\n\n"; 34 } else { 35 echo "結果: パスワードは一致しませんでした。ログイン失敗。\n\n"; 36 } 37 38 // シナリオ2: ユーザーが間違ったパスワードを入力した場合 39 $inputPasswordWrong = "WrongPassword123!"; // 意図的に間違ったパスワード 40 echo "入力されたパスワード (間違っている場合): " . $inputPasswordWrong . "\n"; 41 42 if (password_verify($inputPasswordWrong, $hashedPassword)) { 43 echo "結果: パスワードは一致しました。ログイン成功。\n"; 44 } else { 45 echo "結果: パスワードは一致しませんでした。ログイン失敗。\n"; 46 } 47} 48 49// 実際の使用例として、ユーザーが設定するパスワードを引数に渡します。 50$userProvidedPassword = "MySecretPassword@123"; 51demonstratePasswordVerification($userProvidedPassword); 52 53?>
PHPのpassword_verify関数は、ユーザーが入力した生のパスワードと、データベースなどに安全に保存されているハッシュ化されたパスワードが一致するかどうかを検証するために使用されます。パスワードをそのまま保存することはセキュリティ上のリスクが大きいため、通常はpassword_hash関数などで不可逆なハッシュ形式に変換して保存します。
この関数は、第一引数$passwordにユーザーが入力した生のパスワードを、第二引数$hashにはデータベースなどから取得したハッシュ化されたパスワードを指定します。その結果、パスワードが有効に一致すればtrueを、一致しなければfalseをブール値として返します。
サンプルコードでは、まずpassword_hash関数でパスワードをハッシュ化し、ユーザー登録時に保存される状態をシミュレートしています。次に、ユーザーが正しいパスワードを入力した場合と、意図的に間違ったパスワードを入力した場合の二つのシナリオでpassword_verify関数を呼び出し、パスワードが正しく検証される様子を示しています。これにより、Webアプリケーションにおける安全なパスワード認証の基本的な仕組みを理解できます。
password_verifyは、password_hashで生成されたパスワードのハッシュ値と、ユーザーが入力した生のパスワードが一致するかを安全に検証する関数です。
最も重要な注意点として、生のパスワードを直接データベースに保存することは絶対に避けてください。 必ずpassword_hashでハッシュ化してからデータベースに保存し、ログイン時にはpassword_verifyを使用して検証します。
password_hashは同じパスワードでも実行ごとに異なるハッシュを生成しますが、password_verifyはこの違いを正しく扱えるため問題ありません。また、この関数はパスワードの推測攻撃(ブルートフォース攻撃)を防ぐため、意図的に検証処理に時間をかけることでセキュリティを強化しています。この一連の流れを理解し、正しく利用することがウェブアプリケーションのセキュリティには不可欠です。
PHP password_verify でパスワード一致しない検証
1<?php 2 3/** 4 * password_verify() 関数の使用例を示します。 5 * 正しいパスワードと間違ったパスワードの両方で検証を行い、 6 * password_verify() がどのような結果を返すかを確認します。 7 */ 8function demonstratePasswordVerification(): void 9{ 10 // ユーザーが入力したパスワードを想定 11 $userProvidedPassword = 'MySecretPassword123!'; 12 13 // パスワードをハッシュ化します。 14 // password_hash() は、安全なパスワードハッシュを生成するために推奨される関数です。 15 // PASSWORD_DEFAULT は、現在推奨されているハッシュアルゴリズム(PHP 8ではBcrypt)を使用します。 16 // 自動的にソルトが生成され、ハッシュに埋め込まれます。 17 $hashedPassword = password_hash($userProvidedPassword, PASSWORD_DEFAULT); 18 19 // ハッシュ化に失敗した場合の基本的なエラーチェック 20 if ($hashedPassword === false) { 21 echo "エラー: パスワードのハッシュ化に失敗しました。\n"; 22 return; 23 } 24 25 echo "--- パスワード検証デモンストレーション ---\n\n"; 26 echo "元のパスワード: '{$userProvidedPassword}'\n"; 27 echo "ハッシュ化されたパスワード: '{$hashedPassword}'\n\n"; 28 29 // ---------------------------------------------------- 30 // シナリオ1: 正しいパスワードが提供された場合 31 // ---------------------------------------------------- 32 $attemptPasswordCorrect = 'MySecretPassword123!'; 33 echo "シナリオ1: 正しいパスワードが入力された場合\n"; 34 echo "入力されたパスワード: '{$attemptPasswordCorrect}'\n"; 35 36 // password_verify() は、平文のパスワードとハッシュ化されたパスワードを比較します。 37 // パスワードが一致すれば true を、一致しなければ false を返します。 38 $isVerifiedCorrect = password_verify($attemptPasswordCorrect, $hashedPassword); 39 40 if ($isVerifiedCorrect) { 41 echo "結果: ✅ パスワードは一致しました (true)\n\n"; 42 } else { 43 echo "結果: ❌ パスワードは一致しませんでした (false)\n\n"; 44 } 45 46 // ---------------------------------------------------- 47 // シナリオ2: 間違ったパスワードが提供された場合(一致しないケース) 48 // ---------------------------------------------------- 49 $attemptPasswordIncorrect = 'WrongPassword456!'; 50 echo "シナリオ2: 間違ったパスワードが入力された場合(一致しない)\n"; 51 echo "入力されたパスワード: '{$attemptPasswordIncorrect}'\n"; 52 53 $isVerifiedIncorrect = password_verify($attemptPasswordIncorrect, $hashedPassword); 54 55 if ($isVerifiedIncorrect) { 56 echo "結果: ✅ パスワードは一致しました (true)\n\n"; 57 } else { 58 echo "結果: ❌ パスワードは一致しませんでした (false)\n\n"; 59 } 60 61 // ---------------------------------------------------- 62 // シナリオ3: スペースや大文字・小文字の違いがある場合(一致しないケース) 63 // ---------------------------------------------------- 64 $attemptPasswordCaseMismatch = 'mysecretpassword123!'; // 大文字小文字が異なる 65 echo "シナリオ3: 大文字・小文字が異なるパスワードが入力された場合(一致しない)\n"; 66 echo "入力されたパスワード: '{$attemptPasswordCaseMismatch}'\n"; 67 68 $isVerifiedCaseMismatch = password_verify($attemptPasswordCaseMismatch, $hashedPassword); 69 70 if ($isVerifiedCaseMismatch) { 71 echo "結果: ✅ パスワードは一致しました (true)\n\n"; 72 } else { 73 echo "結果: ❌ パスワードは一致しませんでした (false)\n\n"; 74 } 75} 76 77// 関数を実行してデモンストレーションを開始します。 78demonstratePasswordVerification(); 79
PHPのpassword_verify関数は、ユーザーが入力したパスワードが、システムに安全に保存されているハッシュ化されたパスワードと一致するかどうかを検証するために使用されます。この関数は、平文のパスワードを直接比較するのではなく、セキュリティを考慮したハッシュアルゴリズムを用いて安全に照合を行います。
引数には、ユーザーがフォームなどから入力した「平文のパスワード」と、データベースなどに保存されている「ハッシュ化されたパスワード」の2つを指定します。戻り値はbool型で、パスワードが一致すればtrueを、一致しなければfalseを返します。
サンプルコードでは、まずpassword_hash関数で元のパスワードMySecretPassword123!をハッシュ化しています。
シナリオ1では、ハッシュ化されたパスワードと同じ平文のパスワードMySecretPassword123!を用いてpassword_verifyで検証しています。この場合、パスワードは一致するため、trueが返されます。
シナリオ2では、元のパスワードとは異なるWrongPassword456!で検証しています。パスワードが一致しないため、falseが返されます。
シナリオ3では、元のパスワードと大文字・小文字が異なるmysecretpassword123!で検証しています。password_verifyは厳密な文字列一致を要求するため、このような場合もパスワードは一致しないと判断され、falseが返されます。
このようにpassword_verify関数は、ログイン認証などで入力されたパスワードが正しいか否かを安全に確認する際に非常に重要な役割を果たします。
password_verifyは、ユーザーが入力した平文のパスワードと、事前にpassword_hashで生成・保存したハッシュ化済みのパスワードを比較する際に利用する関数です。password_hashは同じパスワードでも毎回異なるハッシュ値を生成するため、ハッシュ同士を直接比較するのではなく、必ずpassword_verifyを使って検証してください。入力されたパスワードが大文字・小文字、スペースを含めハッシュと少しでも異なると「一致しない」と判定され、falseが返されます。データベースには必ずpassword_hashで生成したハッシュのみを保存し、本関数と組み合わせてパスワード認証を行うことで、システムのセキュリティを安全に保つことができます。