在PHP 中, crypt函數是一個用於密碼哈希的經典函數。它支持多種加密算法,例如DES、MD5、Blowfish、SHA-256 和SHA-512 等。使用合適的Salt(鹽)不僅可以增強密碼的安全性,還能控制加密算法和哈希的複雜度。
本文將詳細介紹如何動態生成適用於多種算法的Salt 模板,從而在使用crypt函數時靈活指定算法和鹽值。
$password = 'mypassword';
$salt = '$6$rounds=5000$usesomesillystring$'; // SHA-512 的示例鹽
$hash = crypt($password, $salt);
echo $hash;
在上面示例中, $6$表示使用SHA-512 算法, rounds=5000代表加密迭代次數,後面的字符串是鹽值主體。
演算法 | Salt 前綴 | Salt 長度及說明 |
---|---|---|
DES | 無前綴 | 2字符鹽 |
MD5 | $1$ | 8字符鹽 |
Blowfish | $2a$或$2y$ | 22字符鹽(包含版本和cost參數) |
SHA-256 | $5$ | 可選參數rounds,鹽主體最多16字符 |
SHA-512 | $6$ | 可選參數rounds,鹽主體最多16字符 |
了解這些後,我們就可以根據不同算法動態生成合適的鹽模板。
下面是一個PHP 函數示例,可以根據輸入的算法名稱生成對應格式的鹽模板:
function generateSalt($algorithm = 'sha512', $rounds = 5000) {
// 隨機鹽主體生成函數,長度根據演算法限制調整
function randomSalt($length) {
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./';
$salt = '';
for ($i = 0; $i < $length; $i++) {
$salt .= $chars[random_int(0, strlen($chars) - 1)];
}
return $salt;
}
switch (strtolower($algorithm)) {
case 'des':
// DES 鹽只取前2字符
return substr(randomSalt(2), 0, 2);
case 'md5':
// MD5 鹽格式 $1$salt$
return '$1$' . randomSalt(8) . '$';
case 'blowfish':
// Blowfish 格式 $2y$cost$22charsalt
$cost = 10; // 2位數字,建議在04到31之間
$costStr = str_pad($cost, 2, '0', STR_PAD_LEFT);
return '$2y$' . $costStr . '$' . randomSalt(22);
case 'sha256':
// SHA-256 格式 $5$rounds=xxxx$salt$
return '$5$rounds=' . intval($rounds) . '$' . randomSalt(16) . '$';
case 'sha512':
default:
// SHA-512 格式 $6$rounds=xxxx$salt$
return '$6$rounds=' . intval($rounds) . '$' . randomSalt(16) . '$';
}
}
$password = 'my_secret_password';
// 選擇演算法
$algorithm = 'blowfish';
// 生成對應鹽模板
$salt = generateSalt($algorithm);
// 生成哈希
$hash = crypt($password, $salt);
echo "演算法: {$algorithm}\n";
echo "鹽模板: {$salt}\n";
echo "生成哈希: {$hash}\n";
通過這種方式,你可以非常靈活地控制密碼加密時使用的算法和鹽的參數,增強安全性。
使用更安全的密碼哈希方案,建議考慮PHP 內置的password_hash和password_verify函數,這些函數封裝了底層的複雜性,默認使用強算法並自動處理鹽。
盡量避免手動拼接鹽字符串中的參數,推薦使用可靠的隨機數生成函數如random_int 。
定期根據安全需求調整rounds (迭代次數)以提高抵抗暴力破解的能力。