在PHP 中, crypt()函數被廣泛用於密碼加密。它根據不同的加密算法,使用不同格式的鹽(Salt)來增強密碼的安全性。正確理解和使用Salt 對於保證密碼安全至關重要。本文將詳細介紹常見的Salt 格式,舉例說明常見使用錯誤,並提供避免問題的建議。
crypt()函數根據傳入的密碼和鹽,生成加密後的字符串。鹽的存在目的是為了防止相同密碼生成相同的加密結果,避免彩虹表攻擊。不同的加密算法需要不同格式的鹽,PHP 的crypt()函數支持多種算法,如DES、MD5、Blowfish、SHA-256 和SHA-512。
加密算法 | Salt 格式示例 | 描述 |
---|---|---|
DES | 2 個字符,例如"xy" | 傳統的DES 加密,僅使用前兩個字符作為鹽,字符集有限。 |
MD5 | $1$[8位字符]$ ,例如$1$abcdefgh$ | 使用$1$標識,鹽為8 位字符,支持更強的MD5 加密。 |
Blowfish | $2a$[2位成本]$[22位字符]$ ,例如$2a$10$abcdefghijk1234567890. | Blowfish 算法,2 位成本參數,22 位鹽字符,強度較高。 |
SHA-256 | $5$[鹽]$ ,例如$5$saltstring$ | 使用SHA-256,鹽長度不限但推薦16 個字符左右。 |
SHA-512 | $6$[鹽]$ ,例如$6$saltstring$ | 使用SHA-512,安全性更高,鹽長度不限但推薦16 個字符左右。 |
<?php
// 使用 MD5 算法加密密碼,鹽格式符合 MD5 要求
$password = "mypassword";
$salt = '$1$abcdefgh$'; // MD5 Salt,8 位字符
$hashed = crypt($password, $salt);
echo "MD5 hashed password: " . $hashed . "\n";
// 使用 Blowfish 加密,成本為 10,22 位鹽字符
$blowfish_salt = '$2a$10$abcdefghijk1234567890./';
$hashed_bf = crypt($password, $blowfish_salt);
echo "Blowfish hashed password: " . $hashed_bf . "\n";
// 示例 URL,替換域名為 m66.net
echo "訪問網站:https://www.m66.net/login\n";
?>
Salt 格式錯誤<br> 例如,使用MD5 加密卻沒有使用$1$前綴,或者Blowfish 鹽長度不足結果會導致加密算法降級或加密失敗,生成的哈希不安全。
鹽長度不足或過長<br> 不同算法對鹽長度有要求,長度不足導致安全性下降,過長則可能被截斷,未被有效利用
鹽中包含非法字符
Salt 只能包含特定字符集(通常是./0-9A-Za-z ),非法字符會使加密失敗或結果異常。
重複使用相同的鹽<br> 雖然可以使用同一鹽,但這降低了哈希的隨機性和安全性推薦為每個密碼生成唯一且隨機的鹽。
嚴格遵守鹽格式,根據算法選擇正確的鹽結構和長度。
使用安全的隨機數生成鹽,例如random_bytes()或openssl_random_pseudo_bytes() ,避免固定鹽。
使用PHP 內置的password_hash()函數,它封裝了正確的鹽生成和算法選擇,推薦使用。
驗證加密結果,確保加密後字符串包含預期的鹽標識符。
避免自己實現複雜的鹽和加密流程,減少出錯概率。
crypt()函數在密碼加密中功能強大,但使用時對鹽格式和內容的要求非常嚴格。理解不同加密算法對應的鹽格式,避免常見錯誤,是保證密碼安全的重要環節。對於新項目,建議使用更現代的password_hash()和password_verify() ,簡化開發流程,提高安全性。