Necesito cifrar algunos datos y descifrarlos en un momento posterior. Los datos están vinculados a usuarios específicos. He reunido dos posibles soluciones ...
1 : el primero se deriva de los documentos oficiales (ejemplo # 1 @ enlace ):
function encrypt($toEncrypt)
{
global $key;
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
return base64_encode($iv . mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $toEncrypt, MCRYPT_MODE_CBC, $iv));
}
function decrypt($toDecrypt)
{
global $key;
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$toDecrypt = base64_decode($toDecrypt);
return rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, substr($toDecrypt, $iv_size), MCRYPT_MODE_CBC, substr($toDecrypt, 0, $iv_size)));
}
La clave se genera una vez usando:
pack('H*', bin2hex(openssl_random_pseudo_bytes(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC))));
1.1 : he notado que el resultado cifrado siempre termina en dos signos iguales ('=='). ¿Por qué? - El uso de bin2hex () y hex2bin () en encrypt () y decrypt () en lugar de base64_encode () / base64_decode () respectivamente no produce estos resultados.
1.2 : ¿El uso de bin2hex () / hex2bin () tendrá alguna consecuencia en el resultado (aparte de la longitud)?
1.3 : parece haber cierta discusión sobre si llamar o no una función de ajuste en el resultado de la devolución al descifrar (esto también se aplica a la solución a continuación). ¿Por qué sería necesario?
2 : la segunda solución viene de aquí, Stackoverflow ( enlace ):
function encrypt($key, $toEncrypt)
{
return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $toEncrypt, MCRYPT_MODE_CBC, md5(md5($key))));
}
function decrypt($key, $toDecrypt)
{
return rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode($toDecrypt), MCRYPT_MODE_CBC, md5(md5($key))), "function encrypt($toEncrypt)
{
global $key;
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
return base64_encode($iv . mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $toEncrypt, MCRYPT_MODE_CBC, $iv));
}
function decrypt($toDecrypt)
{
global $key;
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$toDecrypt = base64_decode($toDecrypt);
return rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, substr($toDecrypt, $iv_size), MCRYPT_MODE_CBC, substr($toDecrypt, 0, $iv_size)));
}
");
}
Soy consciente de que ambos enfoques para el manejo de claves son intercambiables, a propósito los hice diferentes a fin de destacar posibles soluciones, siéntase libre de mezclar y combinar.
Personalmente, creo que el primero ofrece una seguridad más estricta, ya que tanto la clave como el vector de inicialización están correctamente aleatorizados. Sin embargo, la segunda solución ofrece alguna forma de no-previsibilidad ya que la clave es única para cada parte de los datos cifrados (a pesar de que sufre bajo la débil aleatorización de md5 ()). La clave podría ser, por ejemplo, el nombre del usuario.
3 : Entonces, ¿cuál es preferible? Estoy un poco en la oscuridad ya que la respuesta de Stackoverflow obtuvo la friolera de 105 votos. Otros pensamientos, consejos?
4 : ¡Pregunta de bonificación !: No soy increíblemente inteligente en cuanto a los aspectos de seguridad del servidor, pero, obviamente, el acceso a los archivos PHP expondría la clave, lo cual, como resultado directo, representaría el cifrado. inútil, asumiendo que el atacante también tiene acceso a la base de datos. ¿Hay alguna manera de ocultar la clave?
¡Gracias por leer y que tengas un buen día!