2010-11-10 18 views
5

que utilice la siguiente función para descifrar los datos en mi servidor:Problema con la función de PHP mcrypt

function decrypt($key, $text) { 
    return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($text), MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND))); 
} 

He leído mucho acerca de no usar BCE sin embargo (y sé que está en desuso por lo que quería cambiar a CBC. simplemente cambiando el modo a:..?

function decrypt($key, $text) { 
    return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($text), MCRYPT_MODE_CBC, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC), MCRYPT_RAND))); 
} 

no funciona Sin embargo, no se generan errores, pero los datos devueltos todavía se cifran

¿Cuál falto

código actualizado - aún con errores:

$key = "hello"; 

$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_DEV_RANDOM); 

function encrypt($key, $text) { 
    return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $text, MCRYPT_MODE_CBC, $iv))); 
} 


function decrypt($key, $text) { 
    return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($text), MCRYPT_MODE_CBC, $iv)); 
} 


$text = 12345; 

echo "Plain Number : " . $text . "<br><br>"; 

$encrypted = encrypt($key, $text); 
echo "AES Number : " . $encrypted . "<br><br>"; 

echo "Plain Number : ". decrypt($key, $encrypted) . "<br><br>"; 

esto debería funcionar - pero devuelve el error:

de bloque en

de bloque en> Advertencia: MCRYPT_ENCRYPT()

[function.mcrypt-encrypt]: The IV parameter must be as long as the blocksize inblocksize in

tamaño de bloques en

+1

¿Los datos de devolución son los mismos que los que ingresó? Si es así, algo anda mal con la función de descifrado. De lo contrario, está funcionando normalmente, y acaba de utilizar la clave equivocada/IV, y recuperó la basura. –

+0

@Marc B - Sí, de hecho estoy ejecutando el cifrado y el descifrado en la misma página, incluso para asegurarme de que la información sea buena, pero obtengo errores. Voy a tratar de ver que algunas de las sugerencias a continuación marcan la diferencia. – JM4

Respuesta

5

Su código actualizado tiene un problema con $iv siendo una variable global que no está disponible en las respectivas funciones en-/decodificación:

$key = "hello"; 

$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_DEV_RANDOM); 

function encrypt($key, $text, $iv) { 
    return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $text, MCRYPT_MODE_CBC, $iv))); 
} 

function decrypt($key, $text, $iv) { 
    return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($text), MCRYPT_MODE_CBC, $iv)); 
} 

$text = 12345; 

echo "Plain Number : " . $text . "<br><br>"; 

$encrypted = encrypt($key, $text, $iv); 
echo "AES Number : " . $encrypted . "<br><br>"; 

echo "Plain Number : ". decrypt($key, $encrypted, $iv) . "<br><br>"; 

O todavía se puede confiar en el mundial $iv por importar en el alcance de la función local:

function encrypt($key, $text) { 
    global $iv; // or use $GLOBALS['iv] instead of $iv in the call below 
    return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $text, MCRYPT_MODE_CBC, $iv))); 
} 

function decrypt($key, $text) { 
    global $iv; // or use $GLOBALS['iv] instead of $iv in the call below 
    return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($text), MCRYPT_MODE_CBC, $iv)); 
} 

pero esto seguramente no es una práctica recomendada, ya que combina el código con las variables globales.

+0

'mcrypt_create_iv' elimina la advertencia, pero parece ser terriblemente lento por alguna razón. – quickshiftin

+0

No estoy seguro por qué, pero en mis sistemas Linux usando 'MCRYPT_DEV_RANDOM' para la llamada a' mcrypt_create_iv' tomó un buen minuto. Sin embargo, el uso de 'MCRYPT_DEV_URANDOM' es prácticamente instantáneo como cabría esperar. – quickshiftin

+1

Sin duda, notará esto específicamente en las máquinas virtuales. Esto se debe a que las VM no tienen una fuente de entropía decente para/dev/random. – Schodemeiss

7

Cuando descifra, necesita usar el mismo IV que cuando cifró. Parece que estás generando una IV nueva y aleatoria durante el descifrado.

Está bien agregar o anteponer IV al texto cifrado. Los IV no son secretos, pero deben ser únicos para cada mensaje cifrado y solo deben usarse una vez.

+1

@cameron - gracias por la ayuda - tendré que mirar hacia atrás en las vías intravenosas, pero en realidad, ¿cuál es el propósito general de una vía intravenosa si ya está usando una clave para cifrar el archivo? en la misma ubicación que los datos, que no es muy seguro si el servidor está en peligro. – JM4

+0

El IV está allí para evitar las técnicas estadísticas de criptoanálisis. No es un secreto, por lo que no importa si se revela.Usar una IV aleatoria para cada mensaje significa que si encriptas el mismo mensaje dos veces con la misma clave obtienes diferentes textos cifrados. Eso significa que un espía no puede buscar patrones en una secuencia de mensajes, incluso si conocen el IV para cada mensaje. Esto es importante incluso si no está encriptando el mismo mensaje repetidamente. –

+0

@cameron - hay una nueva edición arriba que todavía da errores incluso cuando está en la misma página. – JM4

3

¿Cambió el modo al encriptar este texto también?

Además, al usar MCRYPT_MODE_CBC, debe usar la misma clave y IV durante el cifrado y descifrado. La IV aleatorizada no funciona con CBC.

+0

cambié el modo de cifrado también; sin embargo, hasta el último punto, el "IV aleatorizado" no funciona: el código de muestra en php.net parece indicar lo contrario (aunque utiliza tripledes como cifrado): http://www.php.net/manual/en/function. mcrypt-cbc.php – JM4

+0

Creo que @Dan decía que no se puede descifrar con ningún IV antiguo aleatorio, debe ser el mismo que se usó para el cifrado. ECB no usa un IV. –

+0

nueva edición anterior. – JM4

Cuestiones relacionadas