Modelo de almacenamiento cifrado

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. Cifrar los datos es una buena forma de mitigar esta amenaza, pero muy pocas bases de datos ofrecen este tipo de cifrado de datos.

La forma más sencilla para evitar este problema es crear primero un paquete de cifrado 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 cifrado. El script cifra los datos antes de insertarlos en la base de datos, y los descifra al obtenerlos. Véanse las referencias para ejemplos adicionales del funcionamiento del cifrado.

'Hashing'

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ñaPASSWORD_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) . '.';
}

?>