Можно ли преобразовать вывод php склепа () к допустимому MD5?

Вы должны взглянуть на другой пакет npm, отвечающий за составление почтовых сообщений с заголовками, как, например, nodemailer . После нескольких минут поиска я нашел пример с настройкой заголовков и электронной почтой через SES здесь , они используют mailcomposer, который был предшественником nodemailer

UPDATE: [ 116] Кажется, что nodemailer больше не предоставляет метод build, но есть еще один пакет из них nodemailer-ses-transport , который, кажется, делает именно то, что вам нужно, настраивая заголовки и отправляя через SES. [115 ]

6
задан hakre 4 November 2012 в 23:10
поделиться

5 ответов

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

$1$        # 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 == '$') { // $ 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 содержится много данных, которые нам не нужны (и, фактически, не могут быть использованы) для этого процесса, нужна короткая и милая функция, которая не только свяжет эти два метода вместе, но и позволит напрямую вводить выходные данные из 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

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

9
ответ дан 8 December 2019 в 18:42
поделиться

Из http://php.net/crypt:

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

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

Вычисляет хеш MD5 ул. с помощью» RSA Data Security, Inc. Алгоритм выборки сообщений MD5 и возвраты тот хеш.
Если дополнительный raw_output имеет значение true, то md5 обзор вместо этого возвращается в необработанном двоичном формате с длиной 16. Значения по умолчанию ко ЛЖИ.

0
ответ дан 8 December 2019 в 18:42
поделиться

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

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

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

2
ответ дан 8 December 2019 в 18:42
поделиться

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

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

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

2
ответ дан 8 December 2019 в 18:42
поделиться

Из документации это зависит от системы. Можно вызвать алгоритм, используемый путем установки соленого параметра. Из документов:

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

0
ответ дан 8 December 2019 в 18:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: