<?php
/*
md5crypt.php5
--------------
Written by
- Dennis Riehle <selfhtml@riehle-web.com>
Based on
- perl's Crypt::PasswdMD5 by Luis Munoz (lem@cantv.net)
- phyton's md5crypt.py by Michal Wallace http://www.sabren.com/
- /usr/src/libcrypt/crypt.c from FreeBSD 2.2.5-RELEASE
Many thanks to
- Fabian Steiner <info@fabis-site.net>
without him this script would not work!!
Version: 1.0 stable
Last edit: Tue, 13 September 2005 13:49:28 GMT
USAGE
$cryptedpassword = md5crypt_unix ($password [, $salt [, $magicstring ]);
$apachepassword = md5crypt_apache ($password [, $salt]);
DESCRIPTION
unix_md5_crypt() provides a crypt()-compatible interface to the
rather new MD5-based crypt() function found in modern operating systems.
It's based on the implementation found on FreeBSD 2.2.[56]-RELEASE and
contains the following license in it:
"THE BEER-WARE LICENSE" (Revision 42):
<phk@login.dknet.dk> wrote this file. As long as you retain this notice you
can do whatever you want with this stuff. If we meet some day, and you think
this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
apache_md5_crypt() provides a function compatible with Apache's
.htpasswd files. This was contributed by Bryan Hart <bryan@eai.com>.
*/
$itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
// [a-zA-Z0-9./]
function md5crypt_to64($v, $n) {
$ret = '';
while(--$n >= 0) {
$ret .= $itoa64{$v & 0x3f};
$v = $v >> 6;
}
return $ret;
}
function md5crypt_apache($pw, $salt = NULL) {
$Magic = '$apr1$';
return md5crypt_unix($pw, $salt, $Magic);
}
function md5crypt_unix($pw, $salt = NULL, $Magic = '$1$') {
if($salt !== NULL) {
// Take care of the magic string if present
}
// Salt can have up to 8 characters
$salt =
substr($parts[0],
0,
8);
} else {
$salt = '';
}
}
$ctx = $pw . $Magic . $salt;
$final =
pack('H*',
md5($pw .
$salt .
$pw));
for ($pl =
strlen($pw);
$pl >
0;
$pl -=
16) {
$ctx .=
substr($final,
0,
($pl >
16) ?
16 :
$pl);
}
// Now the 'weird' xform
for($i =
strlen($pw);
$i;
$i >>=
1) {
if($i & 1) { // This comes from the original version,
$ctx .=
pack("C",
0);
// where a memset() is done to $final
} else { // before this loop
$ctx .= $pw{0};
}
}
$final =
pack('H*',
md5($ctx));
// The following is supposed to make
// things run slower
for($i = 0; $i < 1000; $i++) {
$ctx1 = '';
if($i & 1) {
$ctx1 .= $pw;
} else {
$ctx1 .=
substr($final,
0,
16);
}
if($i % 3) {
$ctx1 .= $salt;
}
if($i % 7) {
$ctx1 .= $pw;
}
if($i & 1) {
$ctx1 .=
substr($final,
0,
16);
} else {
$ctx1 .= $pw;
}
}
// Final xform
$passwd = '';
$passwd .= md5crypt_to64
((intval(ord($final{0})) <<
16)
$passwd .= md5crypt_to64
((intval(ord($final{1})) <<
16)
$passwd .= md5crypt_to64
((intval(ord($final{2})) <<
16)
$passwd .= md5crypt_to64
((intval(ord($final{3})) <<
16)
$passwd .= md5crypt_to64
((intval(ord($final{4}) <<
16)
$passwd .= md5crypt_to64
((intval(ord($final{11}))),
2);
// Return the final string
return $Magic . $salt . '$' . $passwd;
}
// EOF
?>