首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP password_hash() 密碼雜湊完整指南與最佳實踐

     編輯:PHP 相關知識

PHP 5.5 引入 Password Hashing API,提供 password_hash()、password_verify()、password_needs_rehash()、password_get_info() 四個函式,徹底解決舊式 MD5/SHA1 雜湊易遭彩虹表破解的問題。本文詳細說明用法、原理與遷移策略。

為何棄用 MD5/SHA1?

傳統單向雜湊(MD5、SHA1)速度極快,適合校驗檔案完整性,但不適合儲存密碼:

  • 無鹽值,相同密碼產生相同雜湊,易建立彩虹表反查。
  • 計算速度快,GPU 可每秒嘗試數十億次暴力破解。
  • CSDN 等洩露事件證實:單純 MD5 幾乎等同明文儲存。

password_hash() 核心優勢

  • 內建鹽值:每次產生唯一鹽值,相同密碼雜湊結果不同。
  • 自適應成本:預設使用 BCrypt(PASSWORD_DEFAULT),可透過 cost 參數調整運算強度,隨硬體升級而增加破解難度。
  • 演算法彈性:支援 BCrypt、Argon2i、Argon2id(PHP 7.2+),未來可平滑遷移至更強演算法。
  • 標準化格式:輸出包含演算法、成本、鹽值與雜湊,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 ...
}

遷移舊系統策略

  1. 雙軌並行:登入時先用 password_verify() 驗證新雜湊,失敗再嘗試舊 MD5 驗證;通過後以 password_hash() 重新雜湊存入資料庫,並標記已遷移。
  2. 強制重設:對長期未登入帳號要求重設密碼,機會更新雜湊。
  3. 資料庫欄位:VARCHAR(255) 足夠容納所有支援演算法的輸出。

跨語言驗證考量

password_hash() 輸出為標準 Modular Crypt Format(如 $2y$10$...),多數語言(Node.js、Python、Go、Java)皆有相容函式庫(如 bcrypt、argon2),非 PHP 專屬。若需跨語言驗證,只需引入對應庫即可。

總結

永遠使用 password_hash() / password_verify() 處理密碼。這是 PHP 官方推薦、社區公認最安全、最省心的方案。不要自行實作鹽值、不要使用 MD5/SHA1、不要嘗試「加密」密碼(應為單向雜湊)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved