encriptar - ¿La mejor manera de usar PHP para cifrar y descifrar contraseñas?
encriptar y desencriptar php 7 (8)
Posible duplicado:
Cifrado PHP bidireccional: necesito almacenar contraseñas que puedan recuperarse
Planeo almacenar información de cuentas extranjeras para mis usuarios en mi sitio web, también conocido como nombre de usuario y contraseñas de rapidshare, etc ... Quiero mantener la información segura, pero sé que si hago su información, no puedo recuperarla para su uso posterior .
Base64 se puede descifrar, por lo que no tiene sentido usarlo simplemente. Mi idea es codificar al usuario y aprobarlo antes y después de que se base de esa manera, incluso después de descifrarlo, obtienes un texto de aspecto divertido si intentas descifrarlo. ¿Existe una función php que acepte valores que hagan una mezcla única de una cadena y la descompongan más tarde cuando se vuelva a contabilizar el valor?
¿Alguna sugerencia?
Advertencia de seguridad: Este código no es seguro.
ejemplo de trabajo
define(''SALT'', ''whateveryouwant'');
function encrypt($text)
{
return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, SALT, $text, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND))));
}
function decrypt($text)
{
return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, SALT, base64_decode($text), MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND)));
}
$encryptedmessage = encrypt("your message");
echo decrypt($encryptedmessage);
Advertencia de seguridad : Esta clase no es segura. Está utilizando Rijndael256-ECB , que no es semánticamente seguro. Solo porque "funciona" no significa "es seguro". Además, elimina los espacios de relaves debido a que no utiliza el relleno adecuado.
Encontré esta clase recientemente, ¡funciona como un sueño!
class Encryption {
var $skey = "yourSecretKey"; // you can change it
public function safe_b64encode($string) {
$data = base64_encode($string);
$data = str_replace(array(''+'',''/'',''=''),array(''-'',''_'',''''),$data);
return $data;
}
public function safe_b64decode($string) {
$data = str_replace(array(''-'',''_''),array(''+'',''/''),$string);
$mod4 = strlen($data) % 4;
if ($mod4) {
$data .= substr(''===='', $mod4);
}
return base64_decode($data);
}
public function encode($value){
if(!$value){return false;}
$text = $value;
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->skey, $text, MCRYPT_MODE_ECB, $iv);
return trim($this->safe_b64encode($crypttext));
}
public function decode($value){
if(!$value){return false;}
$crypttext = $this->safe_b64decode($value);
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$decrypttext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $this->skey, $crypttext, MCRYPT_MODE_ECB, $iv);
return trim($decrypttext);
}
}
Y para llamarlo:
$str = "My secret String";
$converter = new Encryption;
$encoded = $converter->encode($str );
$decoded = $converter->decode($encoded);
echo "$encoded<p>$decoded";
Advertencia de seguridad : Este código es inseguro . Además de ser vulnerable a los ataques de texto cifrado elegidos, su dependencia de
unserialize()
hace vulnerable a la inyección de objetos PHP.
Para manejar una cadena / matriz utilizo estas dos funciones:
function encryptStringArray ($stringArray, $key = "Your secret salt thingie") {
$s = strtr(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), serialize($stringArray), MCRYPT_MODE_CBC, md5(md5($key)))), ''+/='', ''-_,'');
return $s;
}
function decryptStringArray ($stringArray, $key = "Your secret salt thingie") {
$s = unserialize(rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode(strtr($stringArray, ''-_,'', ''+/='')), MCRYPT_MODE_CBC, md5(md5($key))), "/0"));
return $s;
}
Es flexible, ya que puede almacenar / enviar a través de la URL una cadena o matriz porque la cadena / matriz se serializa antes del cifrado.
Echa un vistazo a mycrypt (): http://us.php.net/manual/en/book.mcrypt.php
Y si está usando Postgres, hay pgcrypto para el cifrado a nivel de base de datos. (hace que sea más fácil buscar y ordenar)
Esto solo te dará una protección marginal. Si el atacante puede ejecutar un código arbitrario en su aplicación, puede obtener las contraseñas exactamente de la misma manera que su aplicación. Aún podría obtener algo de protección contra algunos ataques de inyección de SQL y copias de seguridad de db mal ubicadas si almacena una clave secreta en un archivo y la utiliza para cifrar en el camino a la db y descifrar al salir. Pero debe usar bindparams para evitar completamente el problema de la inyección de SQL.
Si decide cifrar, debe usar una biblioteca criptográfica de alto nivel para esto, o lo hará mal. Tendrá que hacer que la configuración de la clave, el relleno de mensajes y las comprobaciones de integridad sean correctas, o todo su esfuerzo de encriptación será de poca utilidad. GPGME es una buena opción para un ejemplo. Mcrypt es un nivel demasiado bajo y probablemente te equivocarás.
La mejor idea para cifrar / descifrar sus datos en la base de datos, incluso si tiene acceso al código, es utilizar 2 pases diferentes, una contraseña privada ( user-pass
) para cada usuario y un código privado para todos los usuarios ( system-pass
).
Guión
-
user-pass
se almacena con md5 en la base de datos y se utiliza para validar cada usuario para iniciar sesión en el sistema. Este pase de usuario es diferente para cada usuario. - Cada entrada de usuario en la base de datos tiene en md5 un
system-pass
desystem-pass
para el cifrado / descifrado de los datos. Este paso del sistema es el mismo para cada usuario. - Cada vez que se elimina un usuario del sistema, todos los datos que están encriptados en la versión anterior del sistema tienen que ser encriptados nuevamente para evitar problemas de seguridad.
Una cosa de la que debe ser muy consciente al tratar con el cifrado:
Tratar de ser inteligente e inventarse lo suyo por lo general lo dejará con algo inseguro.
Probablemente sea mejor usar una de las extensiones de criptografía que vienen con PHP.
No debe cifrar las contraseñas, en su lugar, debe marcarlas utilizando un algoritmo como bcrypt. Esta respuesta explica cómo implementar correctamente el hashing de contraseña en PHP . Aún así, aquí está cómo encriptaría / desencriptaría:
$key = ''password to (en/de)crypt'';
$string = '' string to be encrypted ''; // note the spaces
Para Encriptar:
$iv = mcrypt_create_iv(
mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC),
MCRYPT_DEV_URANDOM
);
$encrypted = base64_encode(
$iv .
mcrypt_encrypt(
MCRYPT_RIJNDAEL_128,
hash(''sha256'', $key, true),
$string,
MCRYPT_MODE_CBC,
$iv
)
);
Para descifrar:
$data = base64_decode($encrypted);
$iv = substr($data, 0, mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC));
$decrypted = rtrim(
mcrypt_decrypt(
MCRYPT_RIJNDAEL_128,
hash(''sha256'', $key, true),
substr($data, mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC)),
MCRYPT_MODE_CBC,
$iv
),
"/0"
);
Advertencia : el ejemplo anterior encripta la información, pero no autentica el texto cifrado para evitar la manipulación. No debe confiar en el cifrado no autenticado por seguridad , especialmente porque el código que se proporciona es vulnerable a los ataques de Oracle Oracle.
Ver también:
- https://.com/a/30189841/2224584
- https://.com/a/30166085/2224584
- https://.com/a/30159120/2224584
Además, no solo use una "contraseña" para una clave de cifrado. Las claves de cifrado son cadenas aleatorias.
echo ''Encrypted:'' . "/n";
var_dump($encrypted); // "m1DSXVlAKJnLm7k3WrVd51omGL/05JJrPluBonO9W+9ohkNuw8rWdJW6NeLNc688="
echo "/n";
echo ''Decrypted:'' . "/n";
var_dump($decrypted); // " string to be encrypted "