SSL/SSH protege los datos que viajan desde el cliente al servidor: SSL/SSH no protege los datos persistentes almacenados en una base de datos. SSL es un protocolo que protege los datos mientras viajan por el cable.
Una vez que un atacante obtiene acceso directo a una base de datos (eludiendo el servidor web), los datos sensibles almacenados podrían ser divulgados o mal utilizados, a menos que la información esté protegida por la base de datos misma. Encriptar los datos es una buena forma de mitigar esta amenaza, pero muy pocas bases de datos ofrecen este tipo de encriptación de datos.
La forma más sencilla para evitar este problema es crear primero un paquete de encriptación propio y utilizarlo en los scripts de PHP. Hay muchas extensiones de PHP que pueden ser de ayuda para esto, tales como Mcrypt y Mhash, cubriendo así una amplia variedad de algoritmos de encriptación. El script encripta los datos antes de insertarlos en la base de datos, y los desencripta al obtenerlos. Véanse las referencias para ejemplos adicionales del funcionamiento de la encriptación.
En caso de datos que deban estar realmente ocultos, si no fuera necesaria su representación real, (es decir, que no sean mostrados), quizás convenga utilizar algoritmos hash. El ejemplo más típico del uso del hash es a la hora de almacenar el hash criptográfico de una contraseña en una base de datos, en lugar de almacenar la contraseña en sí.
En PHP 5.5 o posterior las funciones de password proporcionan una forma adecuada de utilizar hash con datos delicados y trabajar con estos hash. En PHP 5.3.7+ se puede utilizar también la biblioteca » password_compat.
password_hash() se emplea para usar un hash con una cadena dada utilizando el algoritmo más fuerte actualmente disponible, mientras que password_verify() comprueba si la contraseña dada coincide con el hash almacenado en la base de datos.
Ejemplo #1 Campo de contraseña con hash
<?php
// Almacenar el hash de la contraseña
$consulta = sprintf("INSERT INTO users(name,pwd) VALUES('%s','%s');",
pg_escape_string($nombre_usuario),
password_hash($contraseña, PASSWORD_DEFAULT));
$resultado = pg_query($conexión, $consulta);
// Consultar si el usuario envió la contraseña correcta
$consulta = sprintf("SELECT pwd FROM users WHERE name='%s';",
pg_escape_string($nombre_usuario));
$fila = pg_fetch_assoc(pg_query($conexión, $consulta));
if ($fila && password_verify($contraseña, $fila['pwd'])) {
echo 'Bienvenido, ' . htmlspecialchars($nombre_usuario) . '!';
} else {
echo 'La autenticación ha fallado para ' . htmlspecialchars($nombre_usuario) . '.';
}
?>
En versiones anteriores de PHP esto se puede realizar con la función crypt().
Ejemplo #2 Contraseña con hash utilizando crypt()
<?php
// Almacenar el hash de la contraseña
// $caracteres_aleatorios se obtuvo, p.ej., utilizando /dev/random
$consulta = sprintf("INSERT INTO users(name,pwd) VALUES('%s','%s');",
pg_escape_string($nombre_usuario),
pg_escape_string(crypt($contraseña, '$2a$07$' . $caracteres_aleatorios . '$')));
$resultado = pg_query($conexión, $consulta);
// Consultar si el usuario envió la contraseña correcta
$consulta = sprintf("SELECT pwd FROM users WHERE name='%s';",
pg_escape_string($nombre_usuario));
$fila = pg_fetch_assoc(pg_query($conexión, $consulta));
if ($fila && crypt($contraseña, $fila['pwd']) == $fila['pwd']) {
echo 'Bienvenido, ' . htmlspecialchars($nombre_usuario) . '!';
} else {
echo 'La autenticación ha fallado para ' . htmlspecialchars($nombre_usuario) . '.';
}
?>