Реализация функции хеширования MySQL

Я знаю, что php имеет функции md5 (), sha1 () и hash (), но я хочу создать хэш, используя функцию MySQL PASSWORD (). До сих пор единственный способ, которым я могу думать, – просто запросить сервер, но мне нужна функция (желательно в php или Perl), которая будет делать то же самое без запроса MySQL вообще.

Например:

MySQL хэш -> 464bb2cb3cf18b66

MySQL5 хэш -> * 01D01F5CA7CA8BA771E03F4AC55EC73C11EFA229

Благодаря!

Я первоначально наткнулся на этот вопрос в своем собственном поиске реализации PHP двух функций хэширования паролей MySQL. Мне не удалось найти какие-либо реализации, поэтому я адаптировал свой собственный исходный код MySQL (sql / password.c). Следующие тесты протестированы и работают в PHP 5.2:

// The following is free for any use provided credit is given where due. // This code comes with NO WARRANTY of any kind, including any implied warranty. /** * MySQL "OLD_PASSWORD()" AKA MySQL323 HASH FUNCTION * This is the password hashing function used in MySQL prior to version 4.1.1 * By Rev. Dustin Fineout 10/9/2009 9:12:16 AM **/ function mysql_old_password_hash($input, $hex = true) { $nr = 1345345333; $add = 7; $nr2 = 0x12345671; $tmp = null; $inlen = strlen($input); for ($i = 0; $i < $inlen; $i++) { $byte = substr($input, $i, 1); if ($byte == ' ' || $byte == "\t") continue; $tmp = ord($byte); $nr ^= ((($nr & 63) + $add) * $tmp) + (($nr << 8) & 0xFFFFFFFF); $nr2 += (($nr2 << 8) & 0xFFFFFFFF) ^ $nr; $add += $tmp; } $out_a = $nr & ((1 << 31) - 1); $out_b = $nr2 & ((1 << 31) - 1); $output = sprintf("%08x%08x", $out_a, $out_b); if ($hex) return $output; return hex_hash_to_bin($output); } //END function mysql_old_password_hash /** * MySQL "PASSWORD()" AKA MySQLSHA1 HASH FUNCTION * This is the password hashing function used in MySQL since version 4.1.1 * By Rev. Dustin Fineout 10/9/2009 9:36:20 AM **/ function mysql_password_hash($input, $hex = true) { $sha1_stage1 = sha1($input, true); $output = sha1($sha1_stage1, !$hex); return $output; } //END function mysql_password_hash /** * Computes each hexidecimal pair into the corresponding binary octet. * Similar to mysql hex2octet function. **/ function hex_hash_to_bin($hex) { $bin = ""; $len = strlen($hex); for ($i = 0; $i < $len; $i += 2) { $byte_hex = substr($hex, $i, 2); $byte_dec = hexdec($byte_hex); $byte_char = chr($byte_dec); $bin .= $byte_char; } return $bin; } //END function hex_hash_to_bin 

Надеюсь, кто-то еще найдет это полезным 🙂

Если вас интересует алгоритм этой функции, загрузите исходный код и посмотрите файл sql / password.c или проверьте эту реализацию.

Да, слишком поздно, но я только что придумал эту реализацию на этой странице: http://dev.mysql.com/doc/refman/5.1/en/password-hashing.html

Вот эквивалентная функция php для пароля mysql;

 function mysql_41_password($in) { $p = sha1($in, true); $p = sha1($p); return '*'. strtoupper($p); } 

Почему вы хотите использовать функцию mysql password ()? Даже документация Mysql рекомендует:

http://dev.mysql.com/doc/refman/5.0/en/encryption-functions.html#function_password

Функция PASSWORD () используется системой аутентификации в MySQL Server; вы не должны использовать его в своих приложениях

Например, вы можете использовать md5 (), который присутствует почти на каждом языке программирования, включая php и perl.

На основе вышеприведенной реализации PHP, вот пример Perl, который работает.

 use Digest::SHA1 qw(sha1 sha1_hex); sub password { "*".uc(sha1_hex(sha1($_[0]))) } 

Функция пароля возвращает то же, что и функция MySQL5 PASSWORD ().

В ответ на вопрос «зачем кому-то это нужно?» Я использую его для создания операторов SQL «CREATE USER», которые не содержат паролей с открытым текстом.

Плохие парни делают это в bash с sha1sum;)

 PHRASE="password"; P1=`echo -n "${PHRASE}"|sha1sum`; P2="*`echo -en $(echo -n ${P1%% *}|sed -E 's/([0-9a-f]{2})/\\\x\1/g')|sha1sum -b`"; PASS="${P2%% *}"; echo "${PASS^^}" 

OT, но все равно … 🙂