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

PHP 5.5+ 密碼哈希 API 完整指南:password_hash、驗證與重哈希策略

     編輯:PHP 綜合知識

PHP 5.5 引入了 Password Hashing API,提供 password_hash()、password_verify()、password_needs_rehash() 等函數,徹底解決了早期 MD5/SHA1 易受彩虹表攻擊、手動管理 Salt 繁瑣等問題。本文深度解析這套 API 的正確使用姿勢。

核心函數速覽

函數用途關鍵特性
password_hash()創建密碼哈希自動生成 Salt、內置 Cost 因子、算法可升級
password_verify()驗證密碼恆定時間比較,防時序攻擊
password_needs_rehash()檢查是否需重哈希算法升級、Cost 調整時自動遷移
password_get_info()獲取哈希元信息解析算法、參數,無需存儲額外字段

1. 創建哈希:password_hash()

<?php
$password = 'user_password_123';

// 最簡單用法:默認 BCRYPT、Cost=10、自動 Salt
$hash = password_hash($password, PASSWORD_BCRYPT);
// 結果示例:$2y$10$uOegXJ09qznQsKvPfxr61uWjpJBxVDH2KGJQVnodzjnglhs2WTwHu

// 進階:自定義 Cost 與 Salt(通常不建議手動指定 Salt)
$options = [
    'cost' => 12, // 更高安全性,CPU 開銷指數級增長
    'salt' => random_bytes(22) // PHP 7+ 建議用 random_bytes,PHP 5.5 用 mcrypt_create_iv
];
$hash = password_hash($password, PASSWORD_BCRYPT, $options);
// 結果示例:$2y$12$JDJ5JDEwJDhsTHV6SGVIQuprRHZnGQsUEtlk8Iem0okH6HPyCoo22
?>

最佳實踐:不要手動指定 Salt,讓 API 自動生成加密安全的隨機 Salt。Cost 值建議 10~12,根據服務器性能調整(驗證耗時 100~300ms 為宜)。

2. 獲取哈希信息:password_get_info()

<?php
$info = password_get_info($hash);
/*
array(3) {
  ["algo"]      => int(1)        // 算法常量
  ["algoName"]  => string(6) "bcrypt"
  ["options"]   => array(1) { ["cost"] => int(12) }
}
*/
?>

無需在數據庫額外存儲算法版本、Cost 等信息,哈希字符串已自包含所有元數據。

3. 智能重哈希:password_needs_rehash()

當安全策略升級(如 Cost 從 10 提升到 12、或遷移至 Argon2)時,無需強制所有用戶重置密碼,僅在登錄時檢查並平滑遷移:

<?php
// 登錄驗證邏輯中
if (password_verify($inputPassword, $storedHash)) {
    // 密碼正確,檢查是否需升級哈希
    if (password_needs_rehash($storedHash, PASSWORD_BCRYPT, ['cost' => 12])) {
        $newHash = password_hash($inputPassword, PASSWORD_BCRYPT, ['cost' => 12]);
        // 更新數據庫存儲的哈希
        updateUserHash($userId, $newHash);
    }
    // 登錄成功...
}
?>

4. 驗證密碼:password_verify()

<?php
$hash = '$2y$12$JDJ5JDEwJDhsTHV6SGVIQuprRHZnGQsUEtlk8Iem0okH6HPyCoo22';

var_dump(password_verify('user_password_123', $hash)); // true
var_dump(password_verify('wrong_password', $hash));    // false
?>

password_verify() 內部使用恆定時間比較,有效防禦時序側信道攻擊。

算法選擇建議

  • PASSWORD_BCRYPT:PHP 5.5+ 可用,廣泛兼容,最大長度 72 字節。
  • PASSWORD_ARGON2I / PASSWORD_ARGON2ID:PHP 7.2+ 可用,抗 GPU 破解能力更強,推薦新項目優先使用。
  • PASSWORD_DEFAULT:隨 PHP 版本自動升級至最強算法,長期項目首選。

遷移舊系統清單

  1. 新增 password_hash 字段(VARCHAR 255),保留舊哈希字段做回滾。
  2. 登錄時先驗證新哈希,失敗則驗證舊哈希(MD5/SHA1)。
  3. 舊哈希驗證通過後,用 password_hash() 重新生成並更新數據庫,清空舊字段。
  4. 定期運行腳本批量遷移未登錄用戶(可發送重置密碼郵件)。

Password Hashing API 讓密碼存儲變得簡單而安全,請立即在項目中替換所有手動哈希邏輯。

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