.htpasswd 是 Apache 基礎認證使用的密碼文件,格式為 username:{SHA}base64_sha1_password。本文提供完整的 PHP 類封裝,支援用戶增刪查、密碼驗證、SHA-1 加密等操作。
user1:{SHA}kGPaD671VNU0OU5lqLiN/h6Q6ac=
user2:{SHA}npMqPEX3kPQTo+x/+ZckHDrIcQI=
user3:{SHA}q1Fh2LTUjjkncp11m0M9WUH5Zrw=
每行:用戶名:{SHA}Base64編碼的SHA1二進制摘要
file = $file;
} else {
throw new InvalidArgumentException("$file doesn't exist.");
}
}
/** 讀取並解析文件 */
private function read(): array {
$pairs = [];
$fh = fopen($this->file, 'r');
while (!feof($fh)) {
$line = rtrim(fgets($fh), "\n");
if (empty($line)) continue;
$parts = explode(':{SHA}', $line, 2);
if (count($parts) === 2) {
$pairs[$parts[0]] = $parts[1];
}
}
fclose($fh);
return $pairs;
}
/** 寫入文件 */
private function write(array $pairs): void {
$lines = [];
foreach ($pairs as $user => $hash) {
$lines[] = "$user:{SHA}$hash";
}
file_put_contents($this->file, implode("\n", $lines) . "\n", LOCK_EX);
}
/** 明文密碼 → {SHA}Base64(SHA1) */
private function getHash(string $clearPassword): string {
return base64_encode(sha1($clearPassword, true));
}
/** 添加用戶 */
public function addUser(string $username, string $clearPassword): bool {
if (empty($username) || empty($clearPassword)) return false;
$all = $this->read();
if (!isset($all[$username])) {
$all[$username] = $this->getHash($clearPassword);
$this->write($all);
return true;
}
return false; // 用戶已存在
}
/** 刪除用戶 */
public function deleteUser(string $username): bool {
$all = $this->read();
if (isset($all[$username])) {
unset($all[$username]);
$this->write($all);
return true;
}
return false;
}
/** 檢查用戶是否存在 */
public function doesUserExist(string $username): bool {
$all = $this->read();
return isset($all[$username]);
}
/** 驗證密碼 */
public function verifyPassword(string $username, string $clearPassword): bool {
$all = $this->read();
if (!isset($all[$username])) return false;
return $all[$username] === $this->getHash($clearPassword);
}
/** 生成明文密碼提示(基於用戶名+鹽值) */
public function getClearPasswordHint(string $username): string {
return strtolower(substr(sha1($username . $this->salt), 4, 12));
}
}
addUser('alice', 'StrongPass123!');
// 驗證登入
if ($handler->verifyPassword('alice', 'input_password')) {
echo '登入成功';
} else {
echo '密碼錯誤';
}
// 檢查存在
if ($handler->doesUserExist('alice')) {
echo '用戶存在';
}
// 獲取密碼提示(非真實密碼,僅作提示)
echo '密碼提示: ' . $handler->getClearPasswordHint('alice');
// 刪除用戶
$handler->deleteUser('alice');
$apr1$ (MD5-based)、$6$ (SHA-512 crypt)。推薦用 password_hash() / password_verify() 配合 htpasswd -B 生成 bcrypt。chmod 640、擁有者 root:www-data,防止 Web 直接讀取$salt 應從配置讀取,不可硬編碼,定期輪換 12]);
// $2y$12$xxxxxxxxxxxxxxxxxxxxxx
// 驗證
if (password_verify('input_password', $hash)) {
// 成功
}
// 需時重新哈希(成本因子變更)
if (password_needs_rehash($hash, PASSWORD_BCRYPT, ['cost' => 14])) {
$newHash = password_hash('StrongPass123!', PASSWORD_BCRYPT, ['cost' => 14]);
// 更新存儲
}
Apache 可通過 mod_auth_basic + AuthBasicProvider dbd 對接資料庫存儲 bcrypt 哈希,比文件更靈活。
本類提供了 .htpasswd 文件的完整 CRUD 操作,適合維護傳統 Apache 認證系統。新專案強烈建議:
password_hash() + PASSWORD_BCRYPT/ARGON2ID