如何用php编辑.htpasswd?

Mah*_*oud 7 apache .htaccess

我有一个受保护的目录,只有.htpasswd上的用户才能访问,但有时它需要用户更改密码或用户名,编辑一个特定的用户名密码到他的用户名他自己

sample users
kevien : kka
mike : mike
Run Code Online (Sandbox Code Playgroud)

而且我想说我想将kevien改为XYZ

密码同样如此

小智 7

我修改了使用所有类型的crypt alghoritms的功能.有人可能觉得它很有用:

/*
Function change password in htpasswd.
Arguments:
$user    > User name we want to change password to.
$newpass > New password
$type    > Type of cryptogrphy: DES, SHA, MD5. 
$salt    > Option: Add your custom salt (hashing string). 
           Salt is applied to DES and MD5 and must be in range 0-9A-Za-z
$oldpass > Option: Add more security, user must known old password to change it. 
           This option is not supported for DES and MD5 without salt!!!
$path    > Path to .htaccess file which contain the password protection. 
           Path to password file is obtained from this .htaccess file. 
*/  

function changePass($user, $newpass, $type="SHA", $salt="", $oldpass="", $path=".htaccess")
{
    switch ($type) {
        case "DES" :
            $salt = substr($salt,0,2);  // Salt must be 2 char range 0-9A-Za-z
            $newpass = crypt($newpass,$salt);
            if ($oldpass != null) {
                $oldpass = crypt($oldpass,$salt);
            }
            break;

        case "SHA" :
            $newpass = '{SHA}'.base64_encode(sha1($newpass, TRUE));
            if ($oldpass != null) {
                $oldpass = '{SHA}'.base64_encode(sha1($oldpass, TRUE));
            }
            break;

        case "MD5" :
            $salt = substr($salt,0,8);  //Salt must be max 8 char range 0-9A-Za-z
            $newpass = crypt_apr1_md5($newpass, $salt);
            if ($oldpass != null) {
                $oldpass = crypt_apr1_md5($oldpass, $salt);
            }
            break;

        default:
            return false;
            break;
    }

    $hta_arr = explode("\n", file_get_contents($path));

    foreach ($hta_arr as $line) {
        $line = preg_replace('/\s+/','',$line); // remove spaces
        if ($line) {
            $line_arr = explode('"', $line);
            if (strcmp($line_arr[0],"AuthUserFile") == 0) {
                $path_htaccess = $line_arr[1];
            }   
        }
    }  
    $htp_arr = explode("\n", file_get_contents($path_htaccess));

    $new_file = "";
    foreach ($htp_arr as $line) {
        $line = preg_replace('/\s+/', '', $line); // remove spaces
        if ($line) {
            list($usr, $pass) = explode(":", $line, 2);
            if (strcmp($user, $usr) == 0) {
                if ($oldpass != null) {
                    if ($oldpass == $pass) {
                        $new_file .= $user.':'.$newpass."\n";
                    } else {
                        return false;
                    }
                } else {
                    $new_file .= $user.':'.$newpass."\n";
                }
            } else {
                $new_file .= $user.':'.$pass."\n";
            }
        }
    }
    $f = fopen($path_htaccess,"w") or die("couldn't open the file");
    fwrite($f, $new_file);
    fclose($f);
    return true;
}
Run Code Online (Sandbox Code Playgroud)

像MD5一样生成Apache的功能:

/**
 * @param string $password
 * @param string|null $salt
 * @ref https://stackoverflow.com/a/8786956
 */
function crypt_apr1_md5($password, $salt = null)
{
    if (!$salt) {
        $salt = substr(base_convert(bin2hex(random_bytes(6)), 16, 36), 1, 8);
    }
    $len = strlen($password);

    $text = $password . '$apr1$' . $salt;

    $bin = pack("H32", md5($password . $salt . $password));

    for ($i = $len; $i > 0; $i -= 16) {
        $text .= substr($bin, 0, min(16, $i));
    }

    for ($i = $len; $i > 0; $i >>= 1) {
        $text .= ($i & 1) ? chr(0) : $password[0];
    }

    $bin = pack("H32", md5($text));

    for ($i = 0; $i < 1000; $i++) {
        $new = ($i & 1) ? $password : $bin;

        if ($i % 3) {
            $new .= $salt;
        }

        if ($i % 7) {
            $new .= $password;
        }

        $new .= ($i & 1) ? $bin : $password;
        $bin = pack("H32", md5($new));
    }

    $tmp = '';

    for ($i = 0; $i < 5; $i++) {
        $k = $i + 6;
        $j = $i + 12;

        if ($j == 16) {
            $j = 5;
        }

        $tmp = $bin[$i] . $bin[$k] . $bin[$j] . $tmp;
    }

    $tmp = chr(0) . chr(0) . $bin[11] . $tmp;
    $tmp = strtr(
        strrev(substr(base64_encode($tmp), 2)),
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
        "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
    );

    return "$" . "apr1" . "$" . $salt . "$" . $tmp;
}
Run Code Online (Sandbox Code Playgroud)

crypt_apr1_md5()在此处进行演示.

请注意,从Apache 2.4开始,支持bcrypt,因此您可以(并且应该)仅password_hash()在新版本的Apache上使用它.


Pri*_*rix 4

Ofc 这只是一个示例,它将读取您当前的文件,找到给定的用户名并更改用户名的密码。

请记住,此代码并不安全,您仍然需要解析用户名和密码,以免破坏您的文件。

    $username = $_POST['user'];
    $password = $_POST['pass'];
    $new_username = $_POST['newuser'];
    $new_password = $_POST['newpass'];
    $action = $_POST['action'];
    //read the file into an array
    $lines = explode("\n", file_get_contents('.htpasswd'));

    //read the array and change the data if found
    $new_file = "";
    foreach($lines as $line)
    {
        $line = preg_replace('/\s+/','',$line); // remove spaces
        if ($line) {
            list($user, $pass) = split(":", $line, 2);
            if ($user == $username) {
                if ($action == "password") {
                    $new_file .= $user.':'.$new_password."\n";
                } else {
                    $new_file .= $new_username.':'.$pass."\n";
                }
            } else {
                $new_file .= $user.':'.$pass."\n";
            }
        }
    }

    //save the information
    $f=fopen(".htpasswd","w") or die("couldn't open the file");
    fwrite($f,$new_file);
    fclose($f);
Run Code Online (Sandbox Code Playgroud)