La extensión mcrypt está en desuso y se eliminará en PHP 7.2 de acuerdo con el comentario publicado aquí . Así que estoy buscando una forma alternativa de cifrar las contraseñas.
Ahora mismo estoy usando algo como
mcrypt_encrypt(MCRYPT_RIJNDAEL_128, md5($key, true), $string, MCRYPT_MODE_CBC, $iv)
Necesito su opinión sobre la forma mejor / más segura de cifrar contraseñas, la contraseña cifrada debería, por supuesto, ser compatible con PHP 7.xx y también debería ser descifrable porque mis clientes quieren tener una opción para 'recuperar' sus contraseñas sin generar una nueva uno.
password_hash
y verificarlospassword_verify
?Respuestas:
Es una buena práctica aplicar hash a las contraseñas para que no se puedan descifrar. Esto hace que las cosas sean un poco más difíciles para los atacantes que pueden haber obtenido acceso a su base de datos o archivos.
Si debe cifrar sus datos y hacer que se puedan descifrar, hay disponible una guía para el cifrado / descifrado seguro en https://paragonie.com/white-paper/2015-secure-php-data-encryption . Para resumir ese enlace:
fuente
Sodium-compat
( github.com/paragonie/sodium_compat ) que funciona en PHP> = 5.2.4Como lo sugiere @rqLizard , puede usar funciones
openssl_encrypt
/openssl_decrypt
PHP en su lugar, lo que proporciona una alternativa mucho mejor para implementar AES (The Advanced Encryption Standard), también conocido como cifrado Rijndael.Según el siguiente comentario de Scott en php.net :
Otras lecturas:
Ejemplos de código
Ejemplo 1
Ejemplo # 2
Ejemplo # 3
Según los ejemplos anteriores, he cambiado el siguiente código que tiene como objetivo encriptar la identificación de sesión del usuario:
dentro:
Para aclarar, el cambio anterior no es una verdadera conversión, ya que los dos cifrados usan un tamaño de bloque diferente y datos cifrados diferentes. Además, el relleno predeterminado es diferente,
MCRYPT_RIJNDAEL
solo admite relleno nulo no estándar. @zaphNotas adicionales (de los comentarios de @ zaph):
MCRYPT_RIJNDAEL_128
) es equivalente a AES , sin embargo, Rijndael 256 (MCRYPT_RIJNDAEL_256
) no es AES-256 ya que 256 especifica un tamaño de bloque de 256 bits, mientras que AES tiene solo un tamaño de bloque: 128 bits. Entonces, básicamente, Rijndael con un tamaño de bloque de 256 bits (MCRYPT_RIJNDAEL_256
) ha sido nombrado erróneamente debido a las elecciones de los desarrolladores de mcrypt . @zaphEl cifrado con diferentes tamaños de bloque para Rijndael produce diferentes datos cifrados.
Por ejemplo,
MCRYPT_RIJNDAEL_256
(no equivalente aAES-256
) define una variante diferente del cifrado de bloque de Rijndael con un tamaño de 256 bits y un tamaño de clave basado en la clave pasada, dondeaes-256-cbc
es Rijndael con un tamaño de bloque de 128 bits con un tamaño de clave de 256 bits. Por lo tanto, están usando diferentes tamaños de bloque que producen datos encriptados completamente diferentes ya que mcrypt usa el número para especificar el tamaño del bloque, donde OpenSSL usó el número para especificar el tamaño de la clave (AES solo tiene un tamaño de bloque de 128 bits). Básicamente, AES es Rijndael con un tamaño de bloque de 128 bits y tamaños de clave de 128, 192 y 256 bits. Por lo tanto, es mejor usar AES, que se llama Rijndael 128 en OpenSSL.fuente
$session_id = rtrim($decryptedSessionId, "\0");
? ¿Es posibleopenssl_decrypt
devolver algunos personajes no deseados al final? ¿Qué pasa si los extremos variables cifradas con 0 (es decirencrypt("abc0")
?"\0"
no es"0"
más que el carácter NULL, cuyo código ASCII es 0x00 (hexadecimal 0).La implementación de PHP puro de Rijndael existe con phpseclib disponible como paquete composer y funciona en PHP 7.3 (probado por mí).
Hay una página en los documentos de phpseclib, que genera código de muestra después de ingresar las variables básicas (cifrado, modo, tamaño de clave, tamaño de bit). Produce lo siguiente para Rijndael, ECB, 256, 256:
un código con mycrypt
funciona así con la biblioteca
*
$term
fuebase64_decoded
fuente
Como se detalla en otras respuestas aquí, la mejor solución que encontré es usar OpenSSL. Está integrado en PHP y no necesita ninguna biblioteca externa. A continuación, se muestran ejemplos sencillos:
Para cifrar:
Para descifrar:
Enlace de referencia: https://www.shift8web.ca/2017/04/how-to-encrypt-and-execute-your-php-code-with-mcrypt/
fuente
Puede usar el paquete phpseclib pollyfill. No puede usar open ssl o libsodium para cifrar / descifrar con rijndael 256. Otro problema, no necesita reemplazar ningún código.
fuente
mcrypt_compat
ejecutando,composer require phpseclib/mcrypt_compat
peroPHP Fatal error: Uncaught Error: Call to undefined function mcrypt_get_key_size() in /app/kohana/classes/Kohana/Encrypt.php:124
sigo usando php7.2.26
y el marco de Kohana. ¿Hay más pasos que realizar después de instalarlo con Composer?require APPPATH . '/vendor/autoload.php';
al final debootstrap.php
.Debería utilizar OpenSSL,
mcrypt
ya que se desarrolla y mantiene de forma activa. Proporciona mayor seguridad, facilidad de mantenimiento y portabilidad. En segundo lugar, realiza el cifrado / descifrado AES mucho más rápido. Utiliza relleno PKCS7 de forma predeterminada, pero puede especificarOPENSSL_ZERO_PADDING
si lo necesita. Para usar con una clave binaria de 32 bytes, puede especificaraes-256-cbc
cuál es mucho más obvia queMCRYPT_RIJNDAEL_128
.Aquí está el ejemplo de código usando Mcrypt:
Y aquí está la versión escrita usando OpenSSL:
Fuente: Si está escribiendo la palabra MCRYPT en su código PHP, lo está haciendo mal .
fuente
Estoy usando esto en PHP 7.2.x, funciona bien para mí:
y luego autenticar el hash con la siguiente función:
Ejemplo:
y para autenticar este hash use el siguiente código:
Eso es todo.
fuente
Como se señaló, no debería almacenar las contraseñas de sus usuarios en un formato que se pueda descifrar. El cifrado reversible proporciona una ruta fácil para que los piratas informáticos encuentren las contraseñas de sus usuarios, lo que se extiende a poner en riesgo las cuentas de sus usuarios en otros sitios en caso de que usen la misma contraseña allí.
PHP proporciona un par de funciones poderosas para el cifrado de hash unidireccional con sal aleatorio,
password_hash()
ypassword_verify()
. Debido a que el hash es automáticamente salado al azar, no hay forma de que los piratas informáticos utilicen tablas precompiladas de hashes de contraseñas para aplicar ingeniería inversa a la contraseña. Establezca laPASSWORD_DEFAULT
opción y las versiones futuras de PHP usarán automáticamente algoritmos más fuertes para generar hashes de contraseña sin que tenga que actualizar su código.fuente
Deberías usar
openssl_encrypt()
function.fuente
Pude traducir mi objeto Crypto
Obtenga una copia de php con mcrypt para descifrar los datos antiguos. Fui a http://php.net/get/php-7.1.12.tar.gz/from/a/mirror , lo compilé y luego agregué la extensión ext / mcrypt (configure; make; make install). Creo que también tuve que agregar la línea extenstion = mcrypt.so al php.ini. Una serie de scripts para crear versiones intermedias de los datos con todos los datos sin cifrar.
Construya una clave pública y privada para openssl
Para cifrar (usando la clave pública) use openssl_seal. Por lo que he leído, openssl_encrypt usando una clave RSA está limitado a 11 bytes menos que la longitud de la clave (Ver http://php.net/manual/en/function.openssl-public-encrypt.php comentario de Thomas Horsten)
Probablemente podría almacenar el binario en bruto.
Para descifrar (usando clave privada)
PD: no puedes cifrar la cadena vacía ("")
PPS Esto es para una base de datos de contraseñas, no para la validación del usuario.
fuente