Cuando se necesite enviar correos continuamente ejemplo listas de distribución, newsfeed etc.
Se almacena en texto plano en alguna tabla aparte sin poder ser relacionado con ID de algún usuario y/o tabla de Login. Si el usuario se quiere desuscribir utilizar tokens para el propósito
NO, el servidor no necesita recibir el email en el login diario. Para esto en la función login el cliente debería de hashear el password de manera sencilla, eliminar algunos nibbles o bytes de los extremos del hash y enviarlo al servidor. (Nota que esto es solo un ejemplo, métodos hay muchos, el punto es No enviar el email en texto plano)
Antes de guardar el email del usuario tenemos que preguntarnos
Antes de guardar el email del usuario tenemos que preguntarnos
En el peor de los casos cuando Dumpean la base de datos completas mediante algun SQLi o algun otro tipo de ataque, muchas veces la información es Lakeada y termina en listas como las de "Have I been pwned" entre otras
Muchas veces el hash del password no es muy fuerte y es fácilmente forcebruteable
En estos casos prueban tu email y password en otros servicios, Lo cual debería de ser una perdida de tiempo no?, por que las personas utilizan un password diferente en cada servicio.
Soluciones:
Como no sabemos a priori que clase de bugs existan en el sistema operativo, servidor web, servidor SQL, Nuestro código y demás. Mas vale estar prevenido y en el peor de los casos no exponer a los usuarios
Un hash del mismo email protegido con alguna key, Importante: Que no sea reversible es decir que teniendo el hash no exista forma de volver al email y/o password originales.
Los siguientes códigos requieren de un archivo key_db.dat el cual se puede generar con dd leyendo de /dev/random o con el método que mas les guste.
metodo con hash_pbkdf2
$halgo = "sha256";
$iterations = 2000000;
$email = "user@example.com";
$password = "P4ssw0rd";
$salt = hash_file($halgo,"key_db.dat",true);
$salida_email = hash_pbkdf2($halgo,$email,$salt,$iterations,0);
$salida_password = hash_pbkdf2($halgo,$password,$salt,$iterations,0);
echo "hash email: $salida_email\n";
echo "hash password: $salida_password\n";
metodo Iterativo con hash_hmac
$halgo = "sha256";
$iterations = 2000000;
$data_email = "user@example.com";
$data_password = "P4ssw0rd";
$i = 0;
do {
$data_email = hash_hmac($halgo,$data_email,$salt,true);
$data_password = hash_hmac($halgo,$data_password,$salt,true);
}while($i++ < ($iterations - 1));
$data_email = hash_hmac($halgo,$data_email,$salt,false);
$data_password = hash_hmac($halgo,$data_password,$salt,false);
echo "hash email: $data_email\n";
echo "hash password: $data_password\n";
metodo Iterativo solo con hash (data y key concatenadas)
$halgo = "sha256";
$iterations = 2000000;
$data_email = "user@example.com";
$data_password = "P4ssw0rd";
$i = 0;
$data_email = substr($email,0);
$data_password = substr($password,0);
do {
$data_email = hash($halgo,$data_email.$salt,true);
$data_password = hash($halgo,$data_password.$salt,true);
}while($i++ < ($iterations - 1));
$data_email = hash($halgo,$data_email.$salt,false);
$data_password = hash($halgo,$data_password.$salt,false);
echo "hash email: $data_email\n";
echo "hash password: $data_password\n";
Depende de la capacidad de tu servidor, sin embargo hay que considerar que el poder de cómputo puede variar bastante a través de los años, y los segundos que ahora tomen hacer esas iteraciones 1 o 2 segundos, en el futuro pueden ser milisegundos. Lo cual facilita un ataque por fuerza bruta a los hashes
Yo consideraría seriamente en dejarlos unos 10 millones, o más aunque nuevamente depende de la capacidad de tu servidor
Saludos