apache 如何使用 PHP 以编程方式构建 APR1-MD5
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1038791/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to programmatically build an APR1-MD5 using PHP
提问by Tom
Much like this questionI want to generate an htpasswd file entry from PHP. However it needs to be the APR1 (Apache) style, as mentioned in the original answer (The answer did not show how to implement the APR1 style), to work with mod_dav_svn.
很像这个问题,我想从 PHP 生成一个 htpasswd 文件条目。但是,它需要是 APR1 (Apache) 样式,如原始答案中所述(答案未显示如何实现 APR1 样式),才能与 mod_dav_svn 一起使用。
I can't seem to find a working implementation that will create the password.
我似乎找不到可以创建密码的工作实现。
I found this (I forget where now):
我找到了这个(我现在忘记在哪里了):
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;
}
But it doesn't generate a working password. I think this might be something to do with the version of apache but am not sure. (I am running on CENTOS 5)
但它不会生成工作密码。我认为这可能与 apache 的版本有关,但我不确定。(我在 CENTOS 5 上运行)
采纳答案by Tom
It turns out I made a mistake and this function does in fact create working APR1 htpasswd entries. They do look different to the ones Apache creates but they do work.
事实证明我犯了一个错误,这个函数实际上创建了工作 APR1 htpasswd 条目。它们看起来与 Apache 创建的不同,但它们确实有效。
回答by Alex Weinstein
Look for existing components that do it on sites like phpclasses.org. One example: http://www.phpclasses.org/browse/package/5066.html.
在 phpclasses.org 等网站上查找可以执行此操作的现有组件。一个例子:http: //www.phpclasses.org/browse/package/5066.html。
回答by joejac
Thanks you! It works like a charm.
谢谢!它就像一个魅力。
Just a small comment: The salt can also contain "./" and "A..Z" besides "a..z0..9", so it is the same string as the 'translate-to' string in the last line. And sometimes you want to set the salt in addition, to create reproducable results, like:
只是一个小评论:除了“a..z0..9”之外,盐还可以包含“./”和“A..Z”,因此它与最后一行中的“translate-to”字符串相同. 有时您还想设置盐,以创建可重现的结果,例如:
function crypt_apr1_md5( $plainpasswd, $salt = '' ) {
$translateTo = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
if ( $salt == '' ) { $salt = substr(str_shuffle($translateTo), 0, 8); }
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;
}
$tmp = strtr(strrev(substr(base64_encode($tmp), 2)),
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
$translateTo);
return '$apr1$'.$salt.'$'.$tmp;
}
回答by Dmitriy Barybin
See on this:
看看这个:
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>
回答by sjobe
This might be a bit hacky, but have you considered using the exec() function to call the command that generates the htpasswd ?
这可能有点 hacky,但是您是否考虑过使用 exec() 函数来调用生成 htpasswd 的命令?

