當前位置: 首頁> 最新文章列表> 將crypt() 與password_verify() 結合使用可以嗎?

將crypt() 與password_verify() 結合使用可以嗎?

M66 2025-06-06

在PHP 中進行密碼哈希和驗證時, crypt()password_verify()是兩個經常被提及的函數。雖然它們都涉及密碼安全處理,但它們的使用方式和設計目的有所不同。因此,開發者可能會疑問:

一、 crypt()函數概述

crypt()是PHP 早期用於加密密碼的函數。它支持多種算法,如:

  • DES(默認)

  • MD5(以$1$開頭)

  • Blowfish(以$2a$ , $2y$等開頭)

  • SHA-256、SHA-512(以$5$ , $6$開頭)

一個典型的crypt()用法如下:

 $password = 'mySecret';
$salt = '$2y$10$' . substr(strtr(base64_encode(random_bytes(16)), '+', '.'), 0, 22);
$hash = crypt($password, $salt);

二、 password_verify()的原理

password_verify()是在PHP 5.5 引入的,專門為驗證使用password_hash()生成的哈希設計的函數。它自動識別哈希使用的算法(如Bcrypt、Argon2)並根據輸入的明文密碼進行比對。

 if (password_verify('mySecret', $hashFromDatabase)) {
    echo '密碼正確';
}

三、可以將crypt()password_verify()結合使用嗎?

簡短回答:不建議,也沒有意義。

雖然password_verify()背後確實是調用了類似crypt()的底層機制,但它只支持其“自家”函數password_hash()生成的哈希格式。如果你使用crypt()自定義哈希,再使用password_verify()來驗證,會出現以下問題:

  • 如果哈希格式不符合password_verify()預期,它將返回false;

  • PHP 內部並沒有保證未來版本對crypt()生成的非標準格式哈希的支持;

  • password_verify()對於錯誤格式的哈希可能根本無法解析,導致驗證始終失敗。

換句話說,兩者雖有關聯,但不是設計為互通的函數對。

四、安全性對比

使用crypt()的風險:

  • 手動管理鹽值和算法選擇,易出錯;

  • 如果使用不當(如使用默認DES 算法或弱鹽值),容易遭受暴力破解;

  • 不具備自動更新算法的機制;

  • 未來兼容性無法保證。

使用password_hash()password_verify()的優勢:

  • 自動選擇安全默認算法(如Bcrypt);

  • 自動生成鹽值;

  • 算法封裝良好,開發者無需關心底層實現;

  • 可通過password_needs_rehash()實現平滑算法升級;

  • 安全性經過現代標準審查。

五、推薦做法

為了獲得更好的安全性和未來兼容性,建議始終使用password_hash()password_verify()搭配使用

 // 註冊或修改密碼時
$hash = password_hash('mySecret', PASSWORD_DEFAULT);

// 登錄時驗證
if (password_verify('mySecret', $hash)) {
    // 驗證成功
}

如果你在舊系統中使用了crypt() ,建議在用戶登錄成功後,使用password_hash()重新生成哈希,並更新數據庫中的值。這種方式可以逐步平滑過渡到更安全的加密方法。

六、結語

雖然crypt()是PHP 中的一員老將,但在密碼處理領域,它已經逐漸被更現代、更安全的password_hash()password_verify()所取代。將crypt()password_verify()結合使用並不能帶來預期的安全性提升,反而可能因不兼容而帶來驗證失敗等問題。因此,最佳實踐是完全採用PHP 提供的password_系列函數來處理用戶密碼*,確保系統的安全性與可維護性。

如需更進一步的安全措施,可以結合使用Argon2 算法: