PHP 5.5 引入 Password Hashing API,提供 password_hash()、password_verify()、password_needs_rehash()、password_get_info() 四個函式,徹底解決舊式 MD5/SHA1 雜湊易遭彩虹表破解的問題。本文詳細說明用法、原理與遷移策略。
傳統單向雜湊(MD5、SHA1)速度極快,適合校驗檔案完整性,但不適合儲存密碼:
PASSWORD_DEFAULT),可透過 cost 參數調整運算強度,隨硬體升級而增加破解難度。password_verify() 可自動解析驗證,無需額外儲存欄位。$pwd = '123456';
$hash = password_hash($pwd, PASSWORD_DEFAULT); // 推薦:自動選擇最佳演算法
// 或指定演算法與成本
$hash = password_hash($pwd, PASSWORD_BCRYPT, ['cost' => 12]);
echo $hash; // 輸出如:$2y$10$4kAu4FNGuolmRmSSHgKEMe3DbG5pm3diikFkiAKNh.Sf1tPbB4uo2
if (password_verify($pwd, $hash)) {
echo '密碼正確';
} else {
echo '密碼錯誤';
}
// 檢查現有雜湊是否符合當前安全策略
if (password_needs_rehash($hash, PASSWORD_DEFAULT, ['cost' => 12])) {
// 重新雜湊並更新資料庫
$newHash = password_hash($pwd, PASSWORD_DEFAULT, ['cost' => 12]);
// UPDATE users SET password = $newHash WHERE ...
}
password_verify() 驗證新雜湊,失敗再嘗試舊 MD5 驗證;通過後以 password_hash() 重新雜湊存入資料庫,並標記已遷移。VARCHAR(255) 足夠容納所有支援演算法的輸出。password_hash() 輸出為標準 Modular Crypt Format(如 $2y$10$...),多數語言(Node.js、Python、Go、Java)皆有相容函式庫(如 bcrypt、argon2),非 PHP 專屬。若需跨語言驗證,只需引入對應庫即可。
永遠使用 password_hash() / password_verify() 處理密碼。這是 PHP 官方推薦、社區公認最安全、最省心的方案。不要自行實作鹽值、不要使用 MD5/SHA1、不要嘗試「加密」密碼(應為單向雜湊)。