Как программно построить APR1-MD5 с помощью PHP

Как и этот вопрос, я хочу сгенерировать запись файла htpasswd из PHP. Однако это должен быть стиль APR1 (Apache), как указано в первоначальном ответе (ответ не показывал, как реализовать стиль APR1), для работы с mod_dav_svn.

Я не могу найти рабочую реализацию, которая создаст пароль.

Я нашел это (я забыл, где сейчас):

function crypt_apr1_md5($plainpasswd) { $salt = substr(str_shuffle("abcdefghijklmnopqrstuvwxyz0123456789"), 0, 8); $len = strlen($plainpasswd); $text = $plainpasswd.'$apr1$'.$salt; $bin = pack("H32", md5($plainpasswd.$salt.$plainpasswd)); 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) : $plainpasswd{0}; } $bin = pack("H32", md5($text)); for($i = 0; $i < 1000; $i++) { $new = ($i & 1) ? $plainpasswd : $bin; if ($i % 3) $new .= $salt; if ($i % 7) $new .= $plainpasswd; $new .= ($i & 1) ? $bin : $plainpasswd; $bin = pack("H32", md5($new)); } 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; } 

Но он не создает рабочий пароль. Я думаю, что это может быть связано с версией apache, но я не уверен. (Я работаю на CENTOS 5)

Оказывается, я допустил ошибку, и эта функция действительно создает рабочие записи APR1 htpasswd. Они отличаются от тех, которые создает Apache, но они действительно работают.

Ищите существующие компоненты, которые делают это на сайтах, таких как phpclasses.org. Один пример: http://www.phpclasses.org/browse/package/5066.html .

Это может быть немного взломанным, но вы считали, что используете функцию exec () для вызова команды, которая генерирует htpasswd?

Спасибо вам! Отлично работает.

Небольшой комментарий: соль также может содержать «./» и «A..Z», кроме «a..z0..9», поэтому это та же строка, что и строка «translate-to» в последней строке , И иногда вы хотите установить соль дополнительно, чтобы создать воспроизводимые результаты, например:

function crypt_apr1_md5( $plainpasswd, $salt = '' ) {
$translateTo = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
if ( $salt == '' ) { $salt = substr(str_shuffle($translateTo), 0, 8); }

$tmp = strtr(strrev(substr(base64_encode($tmp), 2)), "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", $translateTo);
return '$apr1$'.$salt.'$'.$tmp;
}

Смотрите на этом:

 1: private function crypt_apr1_md5($plainpasswd) { </br> 7: for($i = $len; $i > 0; $i >>= 1) { $text .= ($i & 1) ? chr(o) : $plainpasswd{0}; } </br> 16: $tmp = ''; </br>