) (соленый) алгоритм MD5.

я есть несколько строк, которые были зашифрованы с использованиемФункция PHPcrypt().

Выводы выглядят примерно так:

Функция PHPVf/.4.1.$CgCo33ebiHVuFhpwS.kMI0
Функция PHP84..vD4.$Ps1PdaLWRoaiWDKCfjLyV1
Функция PHPor1.RY4.$v3xo04v1yfB7JxDj1sC/J/

Хотя я полагаю, что crypt () использует алгоритм MD5, выходные данные не являются действительными хэшами MD5.

Есть ли способ конвертировать полученные хеши в действительные хеши MD5 (16-байтовые шестнадцатеричные значения)?

Обновить:

Спасибо за ответы, так что ответы до сих пор. Я почти уверен, что используемая функция crypt использует какой-то алгоритм MD5. То, что я хочу сделать, это преобразовать полученный у меня результат в хеш MD5, который выглядит примерно так:

9e107d9d372bb6826bd81d3542a419d6  
e4d909c290d0fb1ca068ffaddf22cbd0  
d41d8cd98f00b204e9800998ecf8427e

(взято изВикипедия)

Есть ли способ конвертировать из хэшей, которые у меня есть, в те, что указаны выше?

 Mihai Limbășan20 янв. 2009 г., 17:18
Не могли бы вы рассказать немного о том, чего вы пытаетесь достичь? Без обид, но это звучит как шаг 1 в рецепте о том, как провести атаку «радужной таблицы» по базе данных паролей, и люди могут не захотеть помогать, если не уверены, что это не для злых целей ...
 Edouard A.20 янв. 2009 г., 17:28
Один результат закодирован в base64, другой - просто в кодировке base16.
 Martin.13 нояб. 2011 г., 22:05
@PaloEbermann: потому что я забыл это
 Paŭlo Ebermann13 нояб. 2011 г., 16:13
@genesis: Почему вы меняете URL-адрес, на который ссылается, а не тот, который показан на странице?

Ответы на вопрос(5)

что ответ на мой первоначальный вопрос - нет, вы не можете конвертировать из одного формата в другой.

Хеши, сгенерированные php crypt (), по-видимому, генерируются версией реализации хеширования FreeBSD MD5, созданной Poul-Henning Kamp.

http://people.freebsd.org/~phk/

$ 1 $ действительно означает, что это хеш MD5, но crypt генерирует случайную соль.. Если вы включите сгенерированную соль, вы найдете тот же результат.

Соль - это base64, закодированная на выходе как хеш.

Используемый алгоритм является общесистемным параметром. Вообще это MD5, вы правы.

http://php.net/crypt:

crypt () возвратит зашифрованную строку, используя стандартный алгоритм шифрования на основе DES Unix или альтернативные алгоритмы, которые могут быть доступны в системе.

Вы хотитеmd5() функция:

Вычисляет хеш MD5 для str с помощью »алгоритма дайджеста сообщений MD5» RSA Data Security, Inc. и возвращает этот хеш.
Если для необязательного raw_output задано значение TRUE, вместо этого возвращается дайджест md5 в необработанном двоичном формате длиной 16. По умолчанию FALSE.

 Paŭlo Ebermann13 нояб. 2011 г., 16:20
На самом деле, один из альтернативных алгоритмов (этот обозначенФункция PHP) (соленый) алгоритм MD5.

зовать алгоритм, используя параметр соли. Из документов:

Тип шифрования запускается аргументом соли. Во время установки PHP определяет возможности функции crypt и принимает соли для других типов шифрования. Если соль не указана, PHP будет автоматически генерировать стандартную двухсимвольную соль по умолчанию, если тип шифрования по умолчанию в системе не равен MD5, и в этом случае генерируется случайная соль, совместимая с MD5.

Решение Вопроса

возможно, этот ответ опоздал на год, но я попробую. В своем собственном ответе вы заметили, чтоcrypt() использует FreeBSD MD5, которая также выполняет некоторые интересные преобразования в соли перед запуском хэша, поэтому результат того, что я собираюсь вам дать, никогда не будет полностью совпадать с результатами вызоваmd5(), Тем не менее, единственная разница между выводом, который вы видите, и форматом, к которому вы привыкли, заключается в том, что вывод, который вы видите, кодируется следующим образом.

Функция PHP        # this indicates that it is MD5
Vf/.4.1.   # these eight characters are the significant portion of the salt
$          # this character is technically part of the salt, but it is ignored
CgCo33eb   # the last 22 characters are the actual hash
iHVuFhpw   # they are base64 encoded (to be printable) using crypt's alphabet
S.kMI0     # floor(22 * 6 / 8) = 16 (the length in bytes of a raw MD5 hash)

Насколько мне известно, алфавит, используемый Crypt выглядит следующим образом:

./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

Итак, учитывая все это, вот как вы можете преобразовать 22-символьный хэш crypt-base64 в 32-символьный хэш base16 (шестнадцатеричный):

Во-первых, вам нужно что-то, чтобы преобразовать base64 (с пользовательским алфавитом) в необработанный 16-байтовый хеш MD5.

define('CRYPT_ALPHA','./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz');
/**
 * Decodes a base64 string based on the alphabet set in constant CRYPT_ALPHA
 * Uses string functions rather than binary transformations, because said
 * transformations aren't really much faster in PHP
 * @params string $str  The string to decode
 * @return string       The raw output, which may include unprintable characters
 */
function base64_decode_ex($str) {
    // set up the array to feed numerical data using characters as keys
    $alpha = array_flip(str_split(CRYPT_ALPHA));
    // split the input into single-character (6 bit) chunks
    $bitArray = str_split($str);
    $decodedStr = '';
    foreach ($bitArray as &$bits) {
        if ($bits == '

Теперь, когда у вас есть необработанные данные, вам понадобится метод для преобразования их в ожидаемый формат base-16, который не может быть проще.

/**
 * Takes an input in base 256 and encodes it to base 16 using the Hex alphabet
 * This function will not be commented.  For more info:
 * @see http://php.net/str-split
 * @see http://php.net/sprintf
 *
 * @param string $str   The value to convert
 * @return string       The base 16 rendering
 */
function base16_encode($str) {
    $byteArray = str_split($str);
    foreach ($byteArray as &$byte) {
        $byte = sprintf('%02x', ord($byte));
    }
    return join($byteArray);
}

Наконец, поскольку вывод crypt включает в себя много данных, которые нам не нужны (и фактически не могут использовать) для этого процесса, короткая и приятная функция не только связывает эти два элемента вместе, но и обеспечивает прямой ввод вывода из склепа

/**
 * Takes a 22 byte crypt-base-64 hash and converts it to base 16
 * If the input is longer than 22 chars (e.g., the entire output of crypt()),
 * then this function will strip all but the last 22.  Fails if under 22 chars
 *
 * @param string $hash  The hash to convert
 * @param string        The equivalent base16 hash (therefore a number)
 */
function md5_b64tob16($hash) {
    if (strlen($hash) < 22) {
        return false;
    }
    if (strlen($hash) > 22) {
        $hash = substr($hash,-22);
    }
    return base16_encode(base64_decode_ex($hash));
}

Учитывая эти функции, представление base16 ваших трех примеров:

3ac3b4145aa7b9387a46dd7c780c1850
6f80dba665e27749ae88f58eaef5fe84
ec5f74086ec3fab34957d3ef0f838154

Конечно, важно помнить, что они всегда были действительными, просто отформатированы по-разному.

) { // $ indicates the end of the string, to stop processing here break; } if (!isset($alpha[$bits])) { // if we encounter a character not in the alphabet return false; // then break execution, the string is invalid } // decbin will only return significant digits, so use sprintf to pad to 6 bits $decodedStr .= sprintf('%06s', decbin($alpha[$bits])); } // there can be up to 6 unused bits at the end of a string, so discard them $decodedStr = substr($decodedStr, 0, strlen($decodedStr) - (strlen($decodedStr) % 8)); $byteArray = str_split($decodedStr, 8); foreach ($byteArray as &$byte) { $byte = chr(bindec($byte)); } return join($byteArray); }

Теперь, когда у вас есть необработанные данные, вам понадобится метод для преобразования их в ожидаемый формат base-16, который не может быть проще.

/**
 * Takes an input in base 256 and encodes it to base 16 using the Hex alphabet
 * This function will not be commented.  For more info:
 * @see http://php.net/str-split
 * @see http://php.net/sprintf
 *
 * @param string $str   The value to convert
 * @return string       The base 16 rendering
 */
function base16_encode($str) {
    $byteArray = str_split($str);
    foreach ($byteArray as &$byte) {
        $byte = sprintf('%02x', ord($byte));
    }
    return join($byteArray);
}

Наконец, поскольку вывод crypt включает в себя много данных, которые нам не нужны (и фактически не могут использовать) для этого процесса, короткая и приятная функция не только связывает эти два элемента вместе, но и обеспечивает прямой ввод вывода из склепа

/**
 * Takes a 22 byte crypt-base-64 hash and converts it to base 16
 * If the input is longer than 22 chars (e.g., the entire output of crypt()),
 * then this function will strip all but the last 22.  Fails if under 22 chars
 *
 * @param string $hash  The hash to convert
 * @param string        The equivalent base16 hash (therefore a number)
 */
function md5_b64tob16($hash) {
    if (strlen($hash) < 22) {
        return false;
    }
    if (strlen($hash) > 22) {
        $hash = substr($hash,-22);
    }
    return base16_encode(base64_decode_ex($hash));
}

Учитывая эти функции, представление base16 ваших трех примеров:

3ac3b4145aa7b9387a46dd7c780c1850
6f80dba665e27749ae88f58eaef5fe84
ec5f74086ec3fab34957d3ef0f838154

Конечно, важно помнить, что они всегда были действительными, просто отформатированы по-разному.

 huitseeker17 дек. 2010 г., 03:52
Боюсь, что вывод md5-crypt не просто отличается от хеша md5 просто base64-кодировкой с пользовательским алфавитом. Рассматривая один из примеров реализации,google.com/codesearch/p?hl=en#eiS4vny31P0/Linux-PAM-0.99.7.0/... md5-crypt также массирует хэши таким образом, чтобы сделать шифрование требовательным к вычислениям (относительно вычислительной мощности, доступной в то время, см. комментарий о Pentium 60 МГц). Решение, которое вы предоставляете, не инвертирует это преобразование.
 buherator04 авг. 2013 г., 16:43
Версии с кодировкой base64 не имеют отступов. Хеши имеют длину 128 бит, поэтому после перехода по 6 битам у вас останется 2 бита. Очевидное решение состоит в том, чтобы использовать их как LSB и использовать индекс как обычно. Странно то, что хотя каждый из предоставленных хэшей заканчивается 00 битными парами, последний символ их представления base64 (из Q) отличается. Можете ли вы объяснить это?
 Dereleased22 сент. 2015 г., 20:26
@buherator, (1/2) извините, я не заметил этого раньше. Во-первых, 22 символа x 6 битов = 132 бита данных. Мы могли бы взять дополнительные 4 бита из 132 Mod 8 и создать еще один байт, но это вряд ли будет правильным решением, потому что (a) это означает, что мы можем генерировать выходные данные только для последнего байта в очень конкретном диапазоне (высоком или высоком). младшего разряда), что кажется маловероятным, и (б) длина хеша MD5 известна в 128 битах. Кажется, это указывает на то, что оставшиеся 4 бита можно отбросить, но переход по этому пути привел меня к другому, в следующем комментарии.
 Dereleased22 сент. 2015 г., 20:32
@buherator, (2/2). Проанализировав примеры хэшей, я заметил, что всегда оставалось мало данных, которые я усекал в последние четыре бита; на самом деле, казалось, что последний символ всегда был относительно небольшим числом, которое будет иметь данные только в двух последних битах. Скорее всего, это означает одну из двух вещей (возможно, обе): (а) Мой пользовательский алфавит B64 неверен. (b) Значения сериализуются в порядке с прямым порядком байтов. Тестирование делает второй случай более вероятным, и использованиеstrrev околоsprintf вbase64_decode_ex исправляет это.
 Dereleased21 дек. 2010 г., 17:40
Святое дерьмо, возвращаясь из-за могилы, чтобы понизить голос и, кроме того, не на основании вопроса? Проблема была в том, что ценности, выходящие изcrypt() функция не выглядела так, как этого хотел аскер - это было решением проблемы аскера с визуальным представлением хеша, а не с созданием хешаmd5() справедливо для хеша, созданногоcrypt(), По моему скромному мнению, это не то, для чего кнопка downvote.

Ваш ответ на вопрос