PHPのパスワードハッシュ化と認証の仕組み

はじめに

パスワードをハッシュ化してデータベースに保存すると、認証時にどのように比較しているのか疑問に思ったことはありませんか? 特に bcrypt では、同じパスワードをハッシュ化しても毎回異なる値になるため、単純な比較 === では認証ができません。

この記事では、PHPの password_hash()password_verify() を使った適切なパスワードのハッシュ化・認証方法について解説します。

前提

PHPの関数を使って説明します。

ポイント

  1. bcrypt でハッシュ化すると、ソルト(Salt)やアルゴリズム情報が含まれる
  2. ハッシュ化されたパスワードとの比較には password_verify() を使用する

ハッシュ化の仕組み

bcrypt のハッシュ構造

password_hash() を使うと、次の情報が含まれたハッシュが生成されます。

$2y$10$K7Qv/N9UimTzM5vL.1GbOebvWSNITC2FNYwOv.Jp6LhAhlW3ZrU4q
部分説明
$2y$bcryptの識別子
10$コスト(計算回数)(2^10 = 1024回)
K7Qv/N9UimTzM5vL.1GbOeソルト(Salt)
bvWSNITC2FNYwOv.Jp6LhAhlW3ZrU4qハッシュ化されたパスワード

重要なポイント

  • 毎回異なるソルトが含まれるため、同じパスワードでも異なるハッシュが生成される
  • アルゴリズム情報も埋め込まれるため、認証時に適切な方法でハッシュを再計算できる

認証時のパスワード比較方法

ソルトやアルゴリズム情報が毎回異なるため、単純な === 比較では認証できません。 そこで password_verify() を使うことで、保存されたハッシュ情報を元に 入力パスワードを同じ方法でハッシュ化 し、比較を行います。

コード例

// パスワードをハッシュ化して保存
$originalPassword = "my_secure_password";
$hashedPassword = password_hash($originalPassword, PASSWORD_BCRYPT);

// ユーザーがログイン時に入力
$inputPassword = "my_secure_password";

// `password_verify` で比較
if (password_verify($inputPassword, $hashedPassword)) {
    echo "認証成功!";
} else {
    echo "認証失敗!";
}

password_verify() は、保存されているハッシュ情報を解析し、適切なソルトとアルゴリズムを使用して入力されたパスワードを再ハッシュ化し、比較します。

単純なハッシュ関数(md5, sha256 など)との違い

md5()sha256() のような単純なハッシュ関数では、同じパスワードは常に同じハッシュになります。

$hashedPassword = hash("sha256", "my_secure_password");
$inputPassword = hash("sha256", "my_secure_password");

if ($inputPassword === $hashedPassword) {
    echo "認証成功!";  // 成功するが、脆弱
}

bcrypt の password_hash() は、毎回異なるソルトを加えるため、単純な比較ができません。 そのため、password_verify() を使用して適切に検証することが重要です。

まとめ

✅ bcrypt の password_hash() は、ソルトとアルゴリズム情報を含むため、毎回異なるハッシュを生成 する
✅ パスワード比較には password_verify() を使用 し、保存されたハッシュの情報を元に適切に検証する
md5()sha256() のような単純なハッシュ関数ではなく、bcrypt を使用することでセキュリティを向上 できる

パスワードの安全な管理のために、適切なハッシュ化と認証方法を理解し、実践していきましょう!