Pregunta

Tengo algunas cadenas que se han cifrado con función PHP crypt () .

Las salidas se parecen a esto:

$1$Vf/.4.1.$CgCo33ebiHVuFhpwS.kMI0
$1$84..vD4.$Ps1PdaLWRoaiWDKCfjLyV1
$1$or1.RY4.$v3xo04v1yfB7JxDj1sC/J/

Si bien creo que crypt () está usando el algoritmo MD5, las salidas no son hashes MD5 válidos.

¿Hay alguna forma de convertir los hashes producidos en hash MD5 válidos (valores hexadecimales de 16 bytes)?


Update:

Gracias por las respuestas hasta ahora. Estoy bastante seguro de que la función de cripta utilizada está utilizando algún tipo de algoritmo MD5. Lo que estoy buscando hacer es convertir la salida que tengo en un hash MD5 que se parece a lo siguiente:

9e107d9d372bb6826bd81d3542a419d6  
e4d909c290d0fb1ca068ffaddf22cbd0  
d41d8cd98f00b204e9800998ecf8427e

(tomado de Wikipedia )

¿Hay alguna forma de convertir los hashes que tengo a los que están arriba?

¿Fue útil?

Solución

Bien, entonces tal vez esta respuesta llegue un año tarde, pero lo intentaré. En su propia respuesta, observa que crypt () está utilizando FreeBSD MD5, que también realiza algunas transformaciones interesantes en la sal antes de ejecutar el hash, por lo que el resultado de lo que estoy a punto de darle nunca coincidirá con los resultados de una llamada a md5 () . Dicho esto, la única diferencia entre el resultado que está viendo y el formato al que está acostumbrado es que el resultado que está viendo está codificado de la siguiente manera

$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)

Que yo sepa, el alfabeto utilizado por la cripta se ve así:

./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

Entonces, con todo esto en mente, así es cómo puede convertir el hash crypt-base64 de 22 caracteres en un hash base16 (hexadecimal) de 32 caracteres:

Primero, necesita algo para convertir el base64 (con alfabeto personalizado) en un hash MD5 de 16 bytes sin procesar.

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 == '

Ahora que tiene los datos sin procesar, necesitará un método para convertirlos al formato base 16 que espera, lo que no podría ser más fácil.

/**
 * 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);
}

Finalmente, dado que la salida de la cripta incluye una gran cantidad de datos que no necesitamos (y, de hecho, no podemos usar) para este proceso, una función corta y dulce no solo para unir estos dos, sino también para permitir entrada de salida de la cripta.

/**
 * 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));
}

Dadas estas funciones, la representación base16 de sus tres ejemplos son:

3ac3b4145aa7b9387a46dd7c780c1850
6f80dba665e27749ae88f58eaef5fe84
ec5f74086ec3fab34957d3ef0f838154

Por supuesto, es importante recordar que siempre fueron válidos, simplemente formateados de manera diferente.

) { // $ 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); }

Ahora que tiene los datos sin procesar, necesitará un método para convertirlos al formato base 16 que espera, lo que no podría ser más fácil.

<*>

Finalmente, dado que la salida de la cripta incluye una gran cantidad de datos que no necesitamos (y, de hecho, no podemos usar) para este proceso, una función corta y dulce no solo para unir estos dos, sino también para permitir entrada de salida de la cripta.

<*>

Dadas estas funciones, la representación base16 de sus tres ejemplos son:

<*>

Por supuesto, es importante recordar que siempre fueron válidos, simplemente formateados de manera diferente.

Otros consejos

$ 1 $ de hecho significa que este es un hash MD5, pero la cripta genera una sal aleatoria. Es por eso que encuentra un valor MD5 diferente. Si incluye la sal generada, encontrará el mismo resultado.

La sal está codificada en base64 en la salida, como el hash.

El algoritmo utilizado es un parámetro de todo el sistema. Generalmente esto es MD5, tienes razón.

Creo que la respuesta a mi pregunta original es no, no se puede convertir de un formato a otro.

Los hash generados por php crypt () parecen ser generados por una versión de la implementación de hash FreeBSD MD5 creada por Poul-Henning Kamp.

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

De la documentación, esto depende del sistema. Puede forzar el algoritmo utilizado estableciendo el parámetro salt. De los documentos:

  

El tipo de cifrado es activado por   El argumento de la sal. En el momento de la instalación,   PHP determina las capacidades de la   función de cripta y aceptará sales   para otros tipos de encriptación. Si no hay sal   se proporciona, PHP generará automáticamente un   sal estándar de dos caracteres por   predeterminado, a menos que el cifrado predeterminado   escriba en el sistema es MD5, en el que   caso de una sal aleatoria compatible con MD5 es   generado.

De http://php.net/crypt :

  

crypt () devolverá una cadena encriptada utilizando el algoritmo de encriptación estándar basado en Unix DES o algoritmos alternativos que pueden estar disponibles en el sistema.

Desea la función md5 () :

  

Calcula el hash MD5 de str usando el & # 187; Algoritmo de resumen de mensajes MD5 de RSA Data Security, Inc., y devuelve ese hash.
  Si el raw_output opcional se establece en TRUE, el resumen md5 se devuelve en formato binario sin formato con una longitud de 16.   El valor predeterminado es FALSO.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top