在日常的系统管理或开发流程中,我们有时需要一个简单的用户验证机制,尤其是在构建命令行工具时。虽然生产环境中我们更倾向于使用 OAuth、JWT 或数据库认证机制,但在某些轻量级场景下,一个基于 crypt() 函数的用户验证工具就足够了。
本文将带你一步一步构建一个基于 crypt() 的 PHP 命令行用户验证工具。
crypt() 是 PHP 内置的加密函数,用于对密码进行单向哈希加密。它可以使用不同的算法(如 DES、MD5、SHA-256、SHA-512),取决于提供的 salt 格式。
$password = 'secret123';
$hashed = crypt($password, '$6$rounds=5000$mysalt$'); // 使用 SHA-512 加密
echo $hashed;
我们需要先定义一个用户密码文件,类似于 Linux 的 /etc/shadow,用于存储用户名和对应的加密密码。
例如,创建 users.txt 文件,内容如下:
alice:$6$rounds=5000$randomsalt$TtXcNpEYgkQq6nGyTT1ZqJK6sOHZ7GUa0OtUzBDwK8DUD.QHrVmMTE6EKH9vdA/5jYrc6IQsb9M4OzhxZs7Hz1
bob:$6$rounds=5000$othersalt$z1MBfFaSzPIcL7PZ8coYumWqaYvKPWhjvOwwBQ25BqNjfGC2THcR2A2E2MBc6m/mM6z2qKNEqgghADnIJo7KO0
创建 auth.php 文件:
<?php
// 检查是否从命令行运行
if (php_sapi_name() !== 'cli') {
exit("请从命令行运行此脚本。\n");
}
// 获取用户名和密码
fwrite(STDOUT, "用户名: ");
$username = trim(fgets(STDIN));
fwrite(STDOUT, "密码: ");
system('stty -echo'); // 隐藏密码输入
$password = trim(fgets(STDIN));
system('stty echo');
fwrite(STDOUT, "\n");
// 读取用户文件
$userFile = __DIR__ . '/users.txt';
if (!file_exists($userFile)) {
exit("用户文件不存在。\n");
}
$found = false;
$lines = file($userFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($lines as $line) {
list($user, $hashed) = explode(':', $line, 2);
if ($user === $username) {
// 验证密码
if (crypt($password, $hashed) === $hashed) {
echo "身份验证成功!欢迎,{$username}。\n";
} else {
echo "密码错误。\n";
}
$found = true;
break;
}
}
if (!$found) {
echo "用户不存在。\n";
}
为用户添加密码可以通过简单的命令行工具完成:
<?php
// 创建新用户加密条目
$username = readline("新用户名: ");
$password = readline("密码: ");
// 生成 salt 和 hash
$salt = base64_encode(random_bytes(8));
$salt = str_replace('+', '.', substr($salt, 0, 16)); // 兼容性处理
$fullSalt = '$6$rounds=5000$' . $salt . '$';
$hashedPassword = crypt($password, $fullSalt);
// 输出结果
echo "{$username}:{$hashedPassword}\n";
// 可追加到 users.txt 文件中
这个工具虽然简单,但在脚本自动化、安全测试或快速原型中非常有用。可以轻松集成到 Bash 脚本、自动部署流程中,甚至用于保护访问 PHP CLI 工具的接口。
对于生产环境,建议还是采用更专业的用户认证机制,并对密码文件进行适当的权限控制。