文中示例使用 MD5 和簡單鹽值屬於過時且不安全的做法。現代項目必須使用 password_hash() / password_verify()(PHP 5.5+),基於 Bcrypt/Argon2 自動處理鹽值與成本因子。
class XBaseModel {
public function validatePassword($password) {
return $this->hashPassword($this->password) === $password;
}
public function hashPassword($password) {
return md5($password); // 彩虹表秒破
}
}
public function validatePassword($password) {
return $this->hashPassword($password, $this->salt) === $this->password;
}
public function hashPassword($password, $salt) {
return md5(md5($password) . $salt); // 仍屬弱哈希
}
public function generateSalt() {
$chars = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$salt = '';
for ($i = 0; $i < 6; $i++) {
$salt .= $chars[mt_rand(0, strlen($chars)-1)];
}
return $salt;
}
public function hashPassword($password, $salt) {
return md5($salt . $password);
}
protected function generateSalt() {
return uniqid('', true); // 微秒級唯一 ID
}
// 註冊/修改密碼時
$hash = password_hash($password, PASSWORD_ARGON2ID); // 或 PASSWORD_BCRYPT
// 存入數據庫:$hash 已包含算法、成本、鹽值
// 登錄驗證時
if (password_verify($inputPassword, $storedHash)) {
// 成功
// 可選:檢查是否需重新哈希(如成本因子升級)
if (password_needs_rehash($storedHash, PASSWORD_ARGON2ID)) {
$newHash = password_hash($inputPassword, PASSWORD_ARGON2ID);
// 更新數據庫
}
}
password_hash 內建處理。舊系統可採用「懶遷移」策略:登錄時驗證舊哈希,通過則用新算法重新哈希並更新庫,逐步淘汰舊方案。