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

PHP 5.5+ 密碼雜湊 API 完整指南:password_hash、verify 與 rehash

     編輯:PHP 綜合知識

引言

PHP 5.5.0 引入 Password Hashing API,提供安全、簡單的密碼雜湊與驗證機制,取代手動 md5()/sha1() + 鹽值的錯誤做法。核心四函式:

  • password_hash() —— 建立雜湊
  • password_verify() —— 驗證密碼
  • password_get_info() —— 取得雜湊資訊
  • password_needs_rehash() —— 檢查是否需重新雜湊

一、建立雜湊:password_hash()

$password = 'foo';
$hash = password_hash($password, PASSWORD_BCRYPT);
// 結果範例:$2y$10$uOegXJ09qznQsKvPfxr61uWjpJBxVDH2KGJQVnodzjnglhs2WTwHu

支援演算法常數:PASSWORD_BCRYPT(預設)、PASSWORD_ARGON2I、PASSWORD_ARGON2ID(PHP 7.2+)。

進階選項:cost 與 salt

$options = [
    'cost' => 12, // BCRYPT 成本因子,預設 10,愈大愈慢愈安全
    'salt' => random_bytes(16), // PHP 7.0+ 建議省略,讓函式自動產生
];
$hash = password_hash($password, PASSWORD_BCRYPT, $options);

注意: PHP 7.0 起 salt 選項已棄用,請讓 API 自行處理。

二、查看雜湊資訊:password_get_info()

var_dump(password_get_info($hash));
/*
array(3) {
  ["algo"]=> int(1)           // 演算法代碼
  ["algoName"]=> string(6) "bcrypt"
  ["options"]=> array(1) { ["cost"]=> int(12) }
}
*/

三、檢查是否需重新雜湊:password_needs_rehash()

當你想提高 cost 或更換演算法時,可在登入驗證成功後呼叫:

if (password_needs_rehash($hash, PASSWORD_BCRYPT, ['cost' => 12])) {
    $newHash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
    // 更新資料庫儲存的 $newHash
}

此函式不需驗證密碼,僅依演算法與選項判斷。

四、驗證密碼:password_verify()

$hash = '$2y$10$JDJ5JDEwJDhsTHV6SGVIQuprRHZnGQsUEtlk8Iem0okH6HPyCoo22';
var_dump(password_verify('foo', $hash)); // true
var_dump(password_verify('bar', $hash)); // false

回傳 bool,內部採用恆定時間比較,防止時序攻擊。

五、完整登入/註冊流程範例

// 註冊
function register($username, $password) {
    $hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
    // INSERT INTO users (username, password_hash) VALUES (?, ?)
}

// 登入
function login($username, $password) {
    // SELECT password_hash FROM users WHERE username = ?
    $hash = $row['password_hash'];
    if (password_verify($password, $hash)) {
        if (password_needs_rehash($hash, PASSWORD_BCRYPT, ['cost' => 12])) {
            $newHash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
            // UPDATE users SET password_hash = ? WHERE username = ?
        }
        return true; // 登入成功
    }
    return false;
}

六、常見誤區與最佳實務

結語

Password Hashing API 是 PHP 官方推薦的密碼儲存標準,簡單、安全、可遷移。請在所有新專案中採用,並逐步遷移舊系統。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
誤區正確做法
自行產生鹽值讓 password_hash() 內建處理
使用 MD5/SHA1一律改用 Password Hashing API
將雜湊存為 CHAR(32)欄位長度至少 VARCHAR(255) 預留未來演算法
雙重雜湊 md5(md5($pwd))無意義,反而降低安全性