php - encriptar - password_hash
¿Puedes convertir la salida de php crypt() a MD5 válido? (5)
$ 1 $ de hecho significa que este es un hash MD5, pero crypt 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.
Tengo algunas cadenas que han sido encriptadas usando la función PHP crypt()
.
Las salidas se ven algo como esto:
$1$Vf/.4.1.$CgCo33ebiHVuFhpwS.kMI0
$1$84..vD4.$Ps1PdaLWRoaiWDKCfjLyV1
$1$or1.RY4.$v3xo04v1yfB7JxDj1sC/J/
Aunque creo que crypt () está usando el algoritmo MD5, las salidas no son hashes MD5 válidos.
¿Hay alguna manera de convertir los hashes producidos en hash MD5 válidos (valores hexadecimales de 16 bytes)?
Actualizar:
Gracias por las respuestas, así que las respuestas hasta ahora. Estoy bastante seguro de que la función crypt utilizada es algún tipo de algoritmo MD5. Lo que quiero 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 anteriores?
De la documentación, esto depende del sistema. Puede forzar el algoritmo utilizado configurando el parámetro de sal. De los documentos:
El tipo de cifrado se desencadena por el argumento salt. En el momento de la instalación, PHP determina las capacidades de la función crypt y aceptará sales para otros tipos de cifrado. Si no se proporciona sal, PHP generará automáticamente una sal estándar de dos caracteres de forma predeterminada, a menos que el tipo de cifrado predeterminado en el sistema sea MD5, en cuyo caso se generará un sal aleatorio compatible con MD5.
Creo que la respuesta a mi pregunta original es no, no se puede convertir de un formato a otro.
Los valores hash generados por php crypt () parecen generados por una versión de la implementación de hash FreeBSD MD5 creada por Poul-Henning Kamp.
OK, quizás esta respuesta sea un año tarde, pero lo intentaré. En su propia respuesta, nota que crypt()
está usando 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 el 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 crypt se ve así:
./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
Entonces, teniendo todo esto en cuenta, así es como se puede convertir el hash crypt-base64 de 22 caracteres en un hash de 32 caracteres base16 (hexadecimal):
En primer lugar, necesita algo para convertir el base64 (con un alfabeto personalizado) en un hash MD5 sin formato de 16 bytes.
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);
}
Ahora que tiene los datos brutos, necesitará un método para convertirlo al formato base-16 que está esperando, 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 crypt incluye una gran cantidad de datos que no necesitamos (y, de hecho, no podemos usar) para este proceso, una función corta y dulce para no solo vincular estos dos sino permitir la entrada directa 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 de base16 de sus tres ejemplos es:
3ac3b4145aa7b9387a46dd7c780c1850
6f80dba665e27749ae88f58eaef5fe84
ec5f74086ec3fab34957d3ef0f838154
Por supuesto, es importante recordar que siempre fueron válidos, solo formateados de manera diferente.
Desde http://php.net/crypt :
crypt () devolverá una cadena cifrada utilizando el algoritmo de cifrado basado en DES estándar de Unix o algoritmos alternativos que pueden estar disponibles en el sistema.
Desea la función md5()
:
Calcula el hash MD5 de str mediante el »RSA Data Security, Inc. MD5 Message-Digest Algorithm, y devuelve ese hash.
Si la opción raw_output se establece en TRUE, el resumen de md5 se devuelve en formato binario sin procesar con una longitud de 16. El valor predeterminado es FALSE.