PHP 中的crypt()函數是一個用於加密字符串(通常是密碼)的核心函數。它基於系統底層的加密算法,通過對輸入字符串進行哈希處理,實現密碼的安全存儲和驗證。雖然crypt()函數的基本用法和目的在各個PHP 版本中保持一致,但其內部實現及支持的算法隨著PHP 和操作系統版本的變化,存在一些重要差異。這些差異會直接影響密碼的安全性和應用的兼容性,理解它們對開發安全穩定的應用至關重要。
crypt()接受兩個參數:
$hashed_password = crypt($password, $salt);
$password是明文密碼或任意字符串;
$salt是用來控制加密算法的鹽值(salt),格式不同決定了加密算法的選擇。
返回值是經過加密處理後的字符串。驗證密碼時,一般會用相同的鹽重新加密輸入密碼,比較結果是否一致。
早期PHP 版本(PHP 4.x、PHP 5.2 及之前)
只支持系統提供的標準DES 加密(基於56 位密鑰,鹽為2 字符),安全性較低。
如果提供的鹽格式不正確, crypt()會退化為使用DES 加密。
PHP 5.3 及以後
開始支持更現代的加密算法,如MD5(鹽格式以$1$開頭),
還支持Blowfish(鹽格式以$2a$或$2y$開頭,取決於PHP 版本)、
SHA-256 ( $5$ ) 和SHA-512 ( $6$ ) 等算法,前提是操作系統的libc 庫支持。
PHP 7.x
繼續完善Blowfish 支持,修復了歷史上的一些安全漏洞(如$2a$的漏洞影響)
PHP 7.3 以後引入$2y$標記,更安全的Blowfish 版本。
對不同系統的支持程度更高,支持更多算法。
PHP 8.x
保持對上述算法的支持,注重安全性和兼容性。
推薦使用PHP 原生的密碼哈希函數password_hash()和password_verify() ,但crypt()依然可用。
crypt()函數實際上是依賴操作系統的libc 庫(如GNU libc、BSD libc)來完成加密運算,因此:
同樣的PHP 版本在不同操作系統(Linux、FreeBSD、Windows)上,支持的算法可能不完全一致。
Windows 上crypt()支持非常有限,通常只支持傳統的DES 加密。
Linux 通常支持多種算法,取決於libc 版本。
不同加密算法的安全性差距巨大。早期的DES 加密算法極易被破解,不應再用於生產環境。支持現代算法(如Blowfish、SHA-512)的PHP 版本和操作系統,可以極大提升密碼存儲的安全性。
如果應用依賴crypt()並且沒有明確指定鹽的格式,升級PHP 版本或遷移操作系統時可能出現密碼驗證失敗。
例如,舊系統只用DES 加密,遷移後變為SHA-512,導致新系統無法正確驗證舊密碼。
因此,建議應用中明確指定鹽格式,或者採用更現代的密碼處理接口。
PHP 官方在5.5 版本引入了password_hash()和password_verify() ,封裝了密碼加密和驗證的細節:
$hash = password_hash($password, PASSWORD_DEFAULT); // 默認使用 bcrypt
if (password_verify($password, $hash)) {
echo "密碼驗證成功";
}
該接口兼容性好,安全性高,能自動選擇最安全的算法。
避免了直接使用crypt()的複雜性和兼容性問題。
未來版本推薦使用此方案替代直接調用crypt() 。
下面示例展示如何用不同的鹽調用crypt() ,並說明加密結果的差異: