Бага crypt ??

Активист

Активист
Команда форума
Собственно:
Win 7 x64 в актуальном состоянии
PHP 5.3.6 (MSVC9 (Visual C++ 2008) Thread Safety как модуль к апачу
Apache/2.2.17

Есть скрипт:
PHP:
<pre>
<?php 
echo crypt("dev", '$1$dW0.is5.$10CH101gGOr1677ZYd517.'); 
?>
Запускаю в файрфоксе показывает:
$1$dW0.is5.$10CH101gGOr1677ZYd517.

Запускаю в IE9 и F5 много раз, показывает по очереди РАЗНЫЕ ХЕШИ:
$1$dW0.is5.$eq2jnCRV2/HXFEQPRonj8/
$1$dW0.is5.$10CH101gGOr1677ZYd517.

ПЕРЕЗАПУСКАЮ АПАЧ, не меняя скрпит
Фаирфокс показывает абсолютно другой хеш:
$1$dW0.is5.$fELOCg/o4M4JSqjT0FAaZ1

IE 9 так же по очереди:
$1$dW0.is5.$PAX1vDQNMC0Ag2U3joEb71
$1$dW0.is5.$fELOCg/o4M4JSqjT0FAaZ1

Еще раз перезагружаю апач, и хеши опять все разные, картина одна и та же! Каждый релоад апача - хеши меняются!

Млять, я такое первый раз в жизни вижу.
 

Активист

Активист
Команда форума
Обновил Apache до 2.2.18 (no ssl), та же хрень.

Дк, что делать, в админку попасть не могу. Сначала грешил на то что дома Win 7 x64, а в офисе Debian Lenny x86, но когда такое увидел - офигел.
 

fixxxer

К.О.
Партнер клуба
системной в винде нет, та замена, с которой собирается пхп, очевидно бажная

mcrypt в руки ;)
 

MiksIr

miksir@home:~$
А другие алгоритмы в crypt как себя ведут? Может $5$ попробовать?
 

Активист

Активист
Команда форума
Именно нужно на основе MD5, т.е., типичный пхп-ный crypt заменить на не бажный, с использованием mcrypt или чистого алогортма шифрования.
Кстати, у кого PHP 5.3.6 Threadsafe MSVC 9, такая же бага присутсвует?
 

Активист

Активист
Команда форума
Спасибо tony2001 за пинок этой баги))

Вот мое решение проблемы:

PHP:
<?php 
echo fixed_crypt("dev", "\$1\$dW0.is5.\$10CH101gGOr1677ZYd517.");

function fixed_crypt($string, $salt = false) {
	if (crypt("test", "$1\$o8l62SpH\$yMK69aN8bdSM9jrg11cVa/") === "$1\$o8l62SpH\$yMK69aN8bdSM9jrg11cVa/") {
		return crypt($string, $salt);
	}
	
	return unix_md5_crypt($string, $salt);
}

function unix_md5_crypt_to64($v, $n) {
	$itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
	$ret = '';
	while (--$n >= 0) {
		$ret .= substr($itoa64, $v & 0x3f, 1);
		$v >>= 6;
	}
	return $ret;
}

function unix_md5_crypt($password, $salt = false) {
		if ($salt === false) {
			$buf = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
	 		$salt = "";
	 		do {$salt .= substr($buf, mt_rand(0, strlen($buf)), 1); } while (strlen($salt) < 8); 
		}
			
	 	if (!preg_match("/^\\$1\\$(.{8,8})\\$.+$/", $salt, $match)) {
	 		return false; // плохая соль
	 	} else {
	 		$salt = $match[1];
	 	}
	 	
	 	$ctx = $password.'$1$'.$salt;
	 	$final = md5($password.$salt.$password, true);
	 	

	 	
	 	for ($pl = strlen($password); $pl > 0; $pl -= 16) {
	 		$ctx .= substr($final, 0, $pl > 16 ? 16 : $pl);
	 	}
	 	
	 	for ($i = strlen($password); $i; $i >>= 1) {
	 		//echo ($i >>= 6);
	 		if ($i & 1) {
	 			$ctx .= pack("C", 0);
	 		} else {
	 			$ctx .= substr($password, 0, 1);
	 		}
	 	}

	 	$final = md5($ctx, true);
	 	
	 	for ($i = 0; $i < 1000; $i++) {
	 		$ctx1 = "";
	 		if ($i & 1) $ctx1 .= $password; else $ctx1 .= substr($final, 0, 16);
	 		if ($i % 3) $ctx1 .= $salt;
	 		if ($i % 7) $ctx1 .= $password;
	 		if ($i & 1) $ctx1 .= substr($final, 0, 16); else {$ctx1 .= $password;}
	 		
	 		$final = md5($ctx1, true);
	 	}
	 	
	 	$crypted = '';
	 	
	 	$crypted .= unix_md5_crypt_to64(intval(ord(substr($final, 0, 1)) << 16)
	 					| intval(ord(substr($final, 6, 1)) << 8)
	 					| intval(ord(substr($final, 12, 1))), 4);
	 					

	 	$crypted .= unix_md5_crypt_to64(intval(ord(substr($final, 1, 1)) << 16)
	 					| intval(ord(substr($final, 7, 1)) << 8)
	 					| intval(ord(substr($final, 13, 1))), 4);

	 	$crypted .= unix_md5_crypt_to64(intval(ord(substr($final, 2, 1)) << 16)
	 					| intval(ord(substr($final, 8, 1)) << 8)
	 					| intval(ord(substr($final, 14, 1))), 4);
	 					
	 	$crypted .= unix_md5_crypt_to64(intval(ord(substr($final, 3, 1)) << 16)
	 					| intval(ord(substr($final, 9, 1)) << 8)
	 					| intval(ord(substr($final, 15, 1))), 4);
	 					
	 	$crypted .= unix_md5_crypt_to64(intval(ord(substr($final, 4, 1)) << 16)
	 					| intval(ord(substr($final, 10, 1)) << 8)
	 					| intval(ord(substr($final, 5, 1))), 4);

	 	$crypted .= unix_md5_crypt_to64(intval(ord(substr($final, 11, 1))), 2);
	 					
	
	 	
	 	return "$1$".$salt."$".$crypted;
	 }
?>
 

tony2001

TeaM PHPClub
Не за что.
Я не вникал в проблему, но уменьшение salt'а не поможет?
Там просто Пьер сказал, что, мол, поведение при салте больше стандартного не определено.
 

Активист

Активист
Команда форума
1. Строго по мануалу. http://ru2.php.net/crypt (expample 1)
2. Если говорить о стандарте, то соль должна браться из хеша
3. Соль менять побывал (точно дело не в ней), не помогает (но например хеш от test идет норм), см. чуть ниже:
(как бы там в репорте описаться, а то я плохо пишу на английском, да и написать собственно не могу, ибо assigned).

PHP:
<?php 
echo unix_md5_crypt("dev", "\$1\$dW0.is5.\$10CH101gGOr1677ZYd517.")."<br>"; // $1$dW0.is5.$em49ePD07X75OTvpVod410 (corrent)
echo crypt("dev", "\$1\$dW0.is5.\$10CH101gGOr1677ZYd517.")."<br>"; // $1$dW0.is5.$mu.mfjr08AYW9dSKpMxBI0 (wrong)
echo crypt("dev", "\$1\$dW0.is5.")."<br>"; // $1$dW0.is5.$mu.mfjr08AYW9dSKpMxBI0 (wrong)
echo crypt("test", "$1\$o8l62SpH\$yMK69aN8bdSM9jrg11cVa/")."<br>"; // $1$o8l62SpH$yMK69aN8bdSM9jrg11cVa/ (correct)
echo crypt("123", "\$1\$dW0dis5d")."<br>"; // $1$dW0.is5.$6BqXoBw/qBlRQfjc78qPC/ (wrong)
echo unix_md5_crypt("123", "\$1\$dW0dis5d")."<br>"; // $1$dW0dis5d$aefdjzUsrNtmf1qSIvPeK1 (correct)


function unix_md5_crypt_to64($v, $n) {
	$itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
	$ret = '';
	while (--$n >= 0) {
		$ret .= substr($itoa64, $v & 0x3f, 1);
		$v >>= 6;
	}
	return $ret;
}

function unix_md5_crypt($password, $salt = false) {
		if ($salt === false) {
			$buf = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
	 		$salt = "";
	 		do {$salt .= substr($buf, mt_rand(0, strlen($buf)), 1); } while (strlen($salt) < 8); 
		}
			
	 	if (!preg_match("/^\\$1\\$(.{8,8})(?:\\$.+)?$/", $salt, $match)) {
	 		return false; // bad salt
	 	} else {
	 		$salt = $match[1];
	 	}
	 	
	 	$ctx = $password.'$1$'.$salt;
	 	$final = md5($password.$salt.$password, true);
	 	

	 	
	 	for ($pl = strlen($password); $pl > 0; $pl -= 16) {
	 		$ctx .= substr($final, 0, $pl > 16 ? 16 : $pl);
	 	}
	 	
	 	for ($i = strlen($password); $i; $i >>= 1) {
	 		//echo ($i >>= 6);
	 		if ($i & 1) {
	 			$ctx .= pack("C", 0);
	 		} else {
	 			$ctx .= substr($password, 0, 1);
	 		}
	 	}

	 	$final = md5($ctx, true);
	 	
	 	for ($i = 0; $i < 1000; $i++) {
	 		$ctx1 = "";
	 		if ($i & 1) $ctx1 .= $password; else $ctx1 .= substr($final, 0, 16);
	 		if ($i % 3) $ctx1 .= $salt;
	 		if ($i % 7) $ctx1 .= $password;
	 		if ($i & 1) $ctx1 .= substr($final, 0, 16); else {$ctx1 .= $password;}
	 		
	 		$final = md5($ctx1, true);
	 	}
	 	
	 	$crypted = '';
	 	
	 	$crypted .= unix_md5_crypt_to64(intval(ord(substr($final, 0, 1)) << 16)
	 					| intval(ord(substr($final, 6, 1)) << 8)
	 					| intval(ord(substr($final, 12, 1))), 4);
	 					

	 	$crypted .= unix_md5_crypt_to64(intval(ord(substr($final, 1, 1)) << 16)
	 					| intval(ord(substr($final, 7, 1)) << 8)
	 					| intval(ord(substr($final, 13, 1))), 4);

	 	$crypted .= unix_md5_crypt_to64(intval(ord(substr($final, 2, 1)) << 16)
	 					| intval(ord(substr($final, 8, 1)) << 8)
	 					| intval(ord(substr($final, 14, 1))), 4);
	 					
	 	$crypted .= unix_md5_crypt_to64(intval(ord(substr($final, 3, 1)) << 16)
	 					| intval(ord(substr($final, 9, 1)) << 8)
	 					| intval(ord(substr($final, 15, 1))), 4);
	 					
	 	$crypted .= unix_md5_crypt_to64(intval(ord(substr($final, 4, 1)) << 16)
	 					| intval(ord(substr($final, 10, 1)) << 8)
	 					| intval(ord(substr($final, 5, 1))), 4);

	 	$crypted .= unix_md5_crypt_to64(intval(ord(substr($final, 11, 1))), 2);
	 					
	
	 	
	 	return "$1$".$salt."$".$crypted;
	 }



?>
 

AmdY

Пью пиво
Команда форума
а браузер был при чём, ты случаем не из гета данные берёшь? я помню дня два убили пока свою багу выловили, мне данные пока синхронизировали работу функции с сишной. косячил я, что-то там с переменной из гета было не так, вспомнить не могу что, нужно риться в архивах, мот найду исходники, если нужно.
 

Активист

Активист
Команда форума
Нет, именно тестовый скрипт (одна строчка), именно так себя вел, почему в разных браузерах разное поведение - не знаю.
 

gs-design

Новичок
Нет, именно тестовый скрипт (одна строчка), именно так себя вел, почему в разных браузерах разное поведение - не знаю.
Не уверен, что поможет, но криптоп пользовался и я. У меня получился вывод, что при очень маленькой длинне "пароля" - крипт генерит разные хеши. Я длину ограничил 6 и проблема пропала. А вообще сейчас перешёл на md5
 

Активист

Активист
Команда форума
Явно бага где-то. Переписаная функция unix_md5_crypt нормально же отрабатывает. Щас проверю на длинных паролях.

Результаты теста:
WIN NT
Код:
D:\Web\var\>..\php53\php.exe .\crypt.php
Platform: WINNT

Test string:  (length: 0) salt: $1$abcabcab, result: [PASS]
        crypt: $1$abcabcab$lrIM13FEUJz/KdeYOFJzO/
        unix_md5_crypt: $1$abcabcab$lrIM13FEUJz/KdeYOFJzO/

Test string: b (length: 1) salt: $1$abcabcab, result: [FAIL]
        crypt: $1$abcabcab$C.60Futrxlo5p1DUYt5ZB0
        unix_md5_crypt: $1$abcabcab$NREZstZf8rFT.LDrKsExb0

Test string: bu (length: 2) salt: $1$abcabcab, result: [FAIL]
        crypt: $1$abcabcab$r9iSKfiYscLh2QSyxlJZI/
        unix_md5_crypt: $1$abcabcab$P5mUQa3n9QdhDoS1.OQcf.

Test string: bug (length: 3) salt: $1$abcabcab, result: [FAIL]
        crypt: $1$abcabcab$lRBzuIendp4zNNKGlRLl1/
        unix_md5_crypt: $1$abcabcab$jvmVnnGWfvSgHx1fN6e/M0

Test string: pass (length: 4) salt: $1$abcabcab, result: [PASS]
        crypt: $1$abcabcab$kWkoFoDhTE.ZKINRyeaAu/
        unix_md5_crypt: $1$abcabcab$kWkoFoDhTE.ZKINRyeaAu/

Test string: buged (length: 5) salt: $1$abcabcab, result: [PASS]
        crypt: $1$abcabcab$IIOhJMvEY.wum9l9j3pxy0
        unix_md5_crypt: $1$abcabcab$IIOhJMvEY.wum9l9j3pxy0

Test string: aaaaaaaaaaaaaaaaaaaaaaaaa (length: 16777215) salt: $1$abcabcab, result: [PASS]
        crypt: $1$abcabcab$SJAD7AXuGE6DToTUuukAc0
        unix_md5_crypt: $1$abcabcab$SJAD7AXuGE6DToTUuukAc0
Linux:
Код:
linux-debian-1:~# /usr/local/php53/bin/php ./test.php
Platform: Linux

Test string:  (length: 0) salt: $1$abcabcab, result: [PASS]
        crypt: $1$abcabcab$lrIM13FEUJz/KdeYOFJzO/
        unix_md5_crypt: $1$abcabcab$lrIM13FEUJz/KdeYOFJzO/

Test string: b (length: 1) salt: $1$abcabcab, result: [PASS]
        crypt: $1$abcabcab$NREZstZf8rFT.LDrKsExb0
        unix_md5_crypt: $1$abcabcab$NREZstZf8rFT.LDrKsExb0

Test string: bu (length: 2) salt: $1$abcabcab, result: [PASS]
        crypt: $1$abcabcab$P5mUQa3n9QdhDoS1.OQcf.
        unix_md5_crypt: $1$abcabcab$P5mUQa3n9QdhDoS1.OQcf.

Test string: bug (length: 3) salt: $1$abcabcab, result: [PASS]
        crypt: $1$abcabcab$jvmVnnGWfvSgHx1fN6e/M0
        unix_md5_crypt: $1$abcabcab$jvmVnnGWfvSgHx1fN6e/M0

Test string: pass (length: 4) salt: $1$abcabcab, result: [PASS]
        crypt: $1$abcabcab$kWkoFoDhTE.ZKINRyeaAu/
        unix_md5_crypt: $1$abcabcab$kWkoFoDhTE.ZKINRyeaAu/

Test string: buged (length: 5) salt: $1$abcabcab, result: [PASS]
        crypt: $1$abcabcab$IIOhJMvEY.wum9l9j3pxy0
        unix_md5_crypt: $1$abcabcab$IIOhJMvEY.wum9l9j3pxy0

Test string: aaaaaaaaaaaaaaaaaaaaaaaaa (length: 16777215) salt: $1$abcabcab, result: [PASS]
        crypt: $1$abcabcab$SJAD7AXuGE6DToTUuukAc0
        unix_md5_crypt: $1$abcabcab$SJAD7AXuGE6DToTUuukAc0

linux-debian-1:~#
Тестовый скрипт:
PHP:
<?php
set_time_limit(10*60);
echo "Platform: ".PHP_OS."\n\n";
test("");
test("b");
test("bu");
test("bug");
test("pass");
test("buged");
test(str_repeat("a", 0xffffff));

function test($text, $salt = '$1$abcabcab') {
	$crypt = crypt($text, $salt);
	$unix_md5_crypt = unix_md5_crypt($text, $salt); 
	echo "Test string: ".substr($text, 0, 25)." (length: ".strlen($text).") salt: {$salt}, result: [".($crypt !== $unix_md5_crypt ? "FAIL" : "PASS")."]\n".
		"\tcrypt: ".$crypt."\n".
		"\tunix_md5_crypt: ".$unix_md5_crypt.
		"\n\n";		
}

function unix_md5_crypt_to64($v, $n) {
	$itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
	$ret = '';
	while (--$n >= 0) {
		$ret .= substr($itoa64, $v & 0x3f, 1);
		$v >>= 6;
	}
	return $ret;
}

function unix_md5_crypt($password, $salt = false) {
		if ($salt === false) {
			$buf = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
	 		$salt = "";
	 		do {$salt .= substr($buf, mt_rand(0, strlen($buf)), 1); } while (strlen($salt) < 8); 
		}
			
	 	if (!preg_match("/^\\$1\\$(.{8,8})(?:\\$.*)?$/", $salt, $match)) {
	 		return false; // bad salt
	 	} else {
	 		$salt = $match[1];
	 	}
	 	
	 	$ctx = $password.'$1$'.$salt;
	 	$final = md5($password.$salt.$password, true);
	 	

	 	
	 	for ($pl = strlen($password); $pl > 0; $pl -= 16) {
	 		$ctx .= substr($final, 0, $pl > 16 ? 16 : $pl);
	 	}
	 	
	 	for ($i = strlen($password); $i; $i >>= 1) {
	 		//echo ($i >>= 6);
	 		if ($i & 1) {
	 			$ctx .= pack("C", 0);
	 		} else {
	 			$ctx .= substr($password, 0, 1);
	 		}
	 	}

	 	$final = md5($ctx, true);
	 	
	 	for ($i = 0; $i < 1000; $i++) {
	 		$ctx1 = "";
	 		if ($i & 1) $ctx1 .= $password; else $ctx1 .= substr($final, 0, 16);
	 		if ($i % 3) $ctx1 .= $salt;
	 		if ($i % 7) $ctx1 .= $password;
	 		if ($i & 1) $ctx1 .= substr($final, 0, 16); else {$ctx1 .= $password;}
	 		
	 		$final = md5($ctx1, true);
	 	}
	 	
	 	$crypted = '';
	 	
	 	$crypted .= unix_md5_crypt_to64(intval(ord(substr($final, 0, 1)) << 16)
	 					| intval(ord(substr($final, 6, 1)) << 8)
	 					| intval(ord(substr($final, 12, 1))), 4);
	 					

	 	$crypted .= unix_md5_crypt_to64(intval(ord(substr($final, 1, 1)) << 16)
	 					| intval(ord(substr($final, 7, 1)) << 8)
	 					| intval(ord(substr($final, 13, 1))), 4);

	 	$crypted .= unix_md5_crypt_to64(intval(ord(substr($final, 2, 1)) << 16)
	 					| intval(ord(substr($final, 8, 1)) << 8)
	 					| intval(ord(substr($final, 14, 1))), 4);
	 					
	 	$crypted .= unix_md5_crypt_to64(intval(ord(substr($final, 3, 1)) << 16)
	 					| intval(ord(substr($final, 9, 1)) << 8)
	 					| intval(ord(substr($final, 15, 1))), 4);
	 					
	 	$crypted .= unix_md5_crypt_to64(intval(ord(substr($final, 4, 1)) << 16)
	 					| intval(ord(substr($final, 10, 1)) << 8)
	 					| intval(ord(substr($final, 5, 1))), 4);

	 	$crypted .= unix_md5_crypt_to64(intval(ord(substr($final, 11, 1))), 2);
	 					
	
	 	
	 	return "$1$".$salt."$".$crypted;
	 }



?>
Вывод: во встроенном алогоритме crypt хеши строки длинной от 1 до 3 байт выдают разные результаты.
 

Активист

Активист
Команда форума
В общем, поставил под винду PHP 5.3 из репозитория, скомпил, поковырялся.

Суть проблемы:
Функция CryptGetHashParam(ctx1, HP_HASHVAL, final, &dwHashLen, 0);
Возвращала ошибку 0xea (ERROR_MORE_DATA), поскольку dwHashLen принимала заначение меньше чем 16, отсюда MD5 шех не ложился в final. Баг только под виндой, причем он мог возникнуть не только от коротких "паролей", но и при salt < 8 байт после $1$.

Итог:
До патча:
Код:
c:\php-sdk\php53dev\vc9\x86\php-5.3-r955767>Release_TS\php.exe D:\crypt.php
Platform: WINNT

Test string:  (length: 0) salt: $1$abcabcab$ds, result: [PASS]
        crypt: $1$abcabcab$lrIM13FEUJz/KdeYOFJzO/
        unix_md5_crypt: $1$abcabcab$lrIM13FEUJz/KdeYOFJzO/

Test string: b (length: 1) salt: $1$abcabcab$ds, result: [FAIL]
        crypt: $1$abcabcab$X.U5BNa/YZGxVaRNaxva.0
        unix_md5_crypt: $1$abcabcab$NREZstZf8rFT.LDrKsExb0

Test string: bu (length: 2) salt: $1$abcabcab$ds, result: [FAIL]
        crypt: $1$abcabcab$UJlf7X6u.uVhVI8B9X3z01
        unix_md5_crypt: $1$abcabcab$P5mUQa3n9QdhDoS1.OQcf.

Test string: bug (length: 3) salt: $1$abcabcab$ds, result: [FAIL]
        crypt: $1$abcabcab$6a1y/ZQ9n8XCm/4ZId0UV1
        unix_md5_crypt: $1$abcabcab$jvmVnnGWfvSgHx1fN6e/M0

Test string: pass (length: 4) salt: $1$abcabcab$ds, result: [PASS]
        crypt: $1$abcabcab$kWkoFoDhTE.ZKINRyeaAu/
        unix_md5_crypt: $1$abcabcab$kWkoFoDhTE.ZKINRyeaAu/

Test string: buged (length: 5) salt: $1$abcabcab$ds, result: [PASS]
        crypt: $1$abcabcab$IIOhJMvEY.wum9l9j3pxy0
        unix_md5_crypt: $1$abcabcab$IIOhJMvEY.wum9l9j3pxy0

Test string: aaaaaaaaaaaaaaaaaaaaaaaaa (length: 256) salt: $1$abcabcab$ds, result: [PASS]
        crypt: $1$abcabcab$yqPfd1IBRJsrkFk6ETsP3.
        unix_md5_crypt: $1$abcabcab$yqPfd1IBRJsrkFk6ETsP3.
После патча:
Код:
c:\php-sdk\php53dev\vc9\x86\php-5.3-r955767>nmake

Служебная программа обслуживания программ Microsoft (R), версия 9.00.30729.01
(C) Корпорация Майкрософт (Microsoft Corporation). Все права защищены.

Recreating build dirs
php_crypt_r.c
   Создается библиотека Release_TS\php5ts.lib и объект Release_TS\php5ts.exp
SAPI sapi\cli build complete

c:\php-sdk\php53dev\vc9\x86\php-5.3-r955767>Release_TS\php.exe D:\crypt.php
Platform: WINNT

Test string:  (length: 0) salt: $1$abcabcab$ds, result: [PASS]
        crypt: $1$abcabcab$lrIM13FEUJz/KdeYOFJzO/
        unix_md5_crypt: $1$abcabcab$lrIM13FEUJz/KdeYOFJzO/

Test string: b (length: 1) salt: $1$abcabcab$ds, result: [PASS]
        crypt: $1$abcabcab$NREZstZf8rFT.LDrKsExb0
        unix_md5_crypt: $1$abcabcab$NREZstZf8rFT.LDrKsExb0

Test string: bu (length: 2) salt: $1$abcabcab$ds, result: [PASS]
        crypt: $1$abcabcab$P5mUQa3n9QdhDoS1.OQcf.
        unix_md5_crypt: $1$abcabcab$P5mUQa3n9QdhDoS1.OQcf.

Test string: bug (length: 3) salt: $1$abcabcab$ds, result: [PASS]
        crypt: $1$abcabcab$jvmVnnGWfvSgHx1fN6e/M0
        unix_md5_crypt: $1$abcabcab$jvmVnnGWfvSgHx1fN6e/M0

Test string: pass (length: 4) salt: $1$abcabcab$ds, result: [PASS]
        crypt: $1$abcabcab$kWkoFoDhTE.ZKINRyeaAu/
        unix_md5_crypt: $1$abcabcab$kWkoFoDhTE.ZKINRyeaAu/

Test string: buged (length: 5) salt: $1$abcabcab$ds, result: [PASS]
        crypt: $1$abcabcab$IIOhJMvEY.wum9l9j3pxy0
        unix_md5_crypt: $1$abcabcab$IIOhJMvEY.wum9l9j3pxy0

Test string: aaaaaaaaaaaaaaaaaaaaaaaaa (length: 256) salt: $1$abcabcab$ds, result: [PASS]
        crypt: $1$abcabcab$yqPfd1IBRJsrkFk6ETsP3.
        unix_md5_crypt: $1$abcabcab$yqPfd1IBRJsrkFk6ETsP3.


c:\php-sdk\php53dev\vc9\x86\php-5.3-r955767>
Ура :)

Сам патч вот этого файла:
http://svn.php.net/repository/php/php-src/branches/PHP_5_3/ext/standard/php_crypt_r.c

Код:
Index: php_crypt_r.c
===================================================================
--- php_crypt_r.c	(revision 311305)
+++ php_crypt_r.c	(working copy)
@@ -197,7 +197,7 @@
 		goto _destroyCtx1;
 	}
 
-	dwHashLen = pwl + sl + pwl;
+	dwHashLen = 16;
 	CryptGetHashParam(ctx1, HP_HASHVAL, final, &dwHashLen, 0);
 	/*  MD5(pw,salt,pw). Valid. */
http://bugs.php.net/patch-display.php?bug_id=54721&patch=fix&revision=latest
 
Сверху