Evitar navegación.
Principal

Howto encriptar passwords en la base de datos

Si estas desarrollando un sistema de proteccion para tu sitio seguramente la autentificación sea mediante un login y un password, entonces deberías plantearte cómo vas a alamacenar esas contraseñas en la base de datos.

¿Cúal es la manera más segura?

Tienes que saber que la información almacenada en la base de datos no es del todo segura porque es accesible para todos los administradores por eso debes almacenarla de tal manera que esa seguridad no se vea má comprometida, por lo tanto para asegurar nuestras contraseñas podriamos utilizar el Message-Digest Algorithm 5 (MD5).

MD5 (acrónimo de Message-Digest Algorithm 5, Algoritmo de Resumen del Mensaje 5) es un algoritmo de reducción criptográfico de 128 bits ampliamente usado. El código MD5 fue diseñado en 1991 y en 2004 fueron divulgados ciertos defectos de seguridad, lo que hará que en un futuro cercano se cambie de este sistema a otro más seguro.

Entonces te preguntarás porqué debería usar MD5 si no es un sistema del todo seguro, pues porque es rapido, fácil y potente, de hecho su gran ventaja es la facilidad y rapidez de uso.

Es de vital importancia comprender que la encriptación de las contraseñas no protegerá nuestro sitio simplemente protegera las propias contraseñas.

Primer Paso

Lo primero que podemos hacer es un pequeño script que nos introduzca un nuevo usuario en nuestra base de datos ysu respectiva contraseña encriptada con MD5.

define("DB_SERVER", "localhost");
define("DB_USER", "usuario");
define("DB_PASS", "password");
define("DB_NAME", "basededatos");
define("TBL_USERS", "nombredetabla");

$connection = mysql_connect(DB_SERVER, DB_USER, DB_PASS) or die(mysql_error());
mysql_select_db(DB_NAME, $connection) or die(mysql_error());

...

function addNewUser($username, $password){
global $connection;
$password = md5($password);
$q = "INSERT INTO ".TBL_USERS." VALUES ('$username', '$password')";
return mysql_query($q, $connection);
}

Segundo Paso

Comprobaremos si los datos de autentificación son correctos.

function checkUserPass($username, $password){
global $connection;

$username = str_replace("'","''",$username)
$password = md5($password);

// Verificamos que el usuario esta en la base de datos
$q = "SELECT password FROM ".TBL_USERS." WHERE username = '$username'";
$result = mysql_query($q, $connection);
if(!$result || (mysql_numrows($result) < 1)){
return 1; //Indicamos el error
}

// Devolvemos el resultado
$dbarray = mysql_fetch_array($result);

// Validamos que los datos son correctos
if($password == $dbarray['password']){
return 0; //Satisfactorio usuario y contraseña confirmadas
}
else{
return 1; //Fallo en la contraseña
}
}

Tercer Paso

Si dispones de contraseñas no encriptadas en tu base de datos y quiere probar su funcionalidad este script, puedes utilizar este otro para poder encriptar todas aquellas que no lo están.

Enlaces Interesantes

Seccion Programación (TuFunción)
Seccion PHP(TuFunción)
Tutorial básocp de AJAX
Diferencia entre PHP ASP y otros lenguajes de programación
Fácil sistema de autentificación de usuarios (PHP)
Tendencia de los lenguajes de programación
Bases de datos y PHP
Consejos para escribir código Javascript
Perl está muriendo
How to Encrypt Passwords in the Database

Enlaces Relacionados


sopa de bytes propuesta por Daniel Solis

La idea que comenta este muchacho es muy buena, pero bien remarco el punto debil, cuando el user envia la contraseña al server, si bien propuso la solucion de utilizar el algoritmo de cifrado en javascript para que ya desde el cliente la contraseña parta cifrada, en algun lugar del xhtml hay una linea que hace referencia al script en javascript, lo que dejaria a simple vista nuestro algoritmo cifrador de codigos y haciendo un analisis de un par de horas tenemos la formula inversa (descifrado), sin necesidad de diccionarios ni nada por el estilo, solo extraer la funcion "f" del js, analizarla un poco y generar la funcion "g=f^-1". Y ya solo quedaria por bajarse la base de datos del server, con los datos encriptados...

Saludos

Como proteger nuestras queridas y amadas claves (passwords)

Es indiscutible, que todo lo que tenga que ver con algoritmos ya conocidos, y peor aun si se cuenta con el codigo fuente a la mano de dichos algoritmos, la seguridad esta realmente comprometida, lo mejor que se puede hacer en estos casos, y que es dificil o imposible para los queridos y amados hakers, crakers, lamers y todo lo relacionado, romper la seguridad de mi siguiente propuesta:

1.- Se puede seguir generando los passwords con los algoritmos que ustedes gusten o se acomodden mejor. Solo que hay que insertar entre los hashes generados bytes aleatorios en ciertas posiciones, no importa en cuales posiciones, siempre y cuando ustedes recuerden o sepan donde se encuentran esas inserciones y las puedan retirar para sus respectivos procesamientos.

2.- No limitar a cierto numero de posisiones los campos de nuestras bases de datos que contengan nuestros passwords, esto con la finalidad de poder colocar nuestro hash con más bytes (las insersiones de bytes aleatorios en posiciones especificas de nuestro hash q nosotros solo sabemos) no importa que la longitud de nuestro hash cresca al doble o triple, la idea es confundir, de tal forma que los amantes de la descodificacion puedan tomar un hash limpio para porcesarlo y descifrarlo.

3.- Cuando hagamos nuestra sopa, tanto con los bytes verdaderos de nuestro hash en cuestion como con los falsos bytes al azar, tendremos un hash inreconocible e indecifrable, muy dificil de separar y cotejar por quienes no conozcan el proceso, en caso de que se roben la base de datos.

4.- Podemos hacer las cosas aun más dificiles para los "hakers", si nosotros creamos nuestros propios algoritmos que recodifiquen la cadena (sopa de bytes), ya sea recorriendo los bytes a la izquierda x posiiones o la derecha o sumarlos o restalos o lo que se les ocurra, obviamente que tenga reversa para poder recuperar la caddena sopa de bytes y retirar los bytes que insertamos al azar en las x posiciones para finalmente obtener nuestro hash totalmente limpio.

5.- Tratandose de seguridad no importa cuanto trabajo y tiempo se tenga que hacer para lograrla (ya que los amados hakers lo invierten sin importar cuanto trabajo se tenga que hacer para loc¿grar desvelar uno o dos hash's), al fin y al cabo quien hace el trabajo es la computadora y aveces invertimos mas recursos en cosas bobas como hacer codigos que según la hora del dia les diga a los usuarios "buenos dias o buenas trades o buenas noches"... o que se yo!

6.- Tambien hay que preocuparse de gran manera de la forma en como el usuario (cliente) envia su clave a nuestro servidor ya que si permitimos que la envien tal cual; alguien la puede tomar durante el trayecto hacia el server y pues de nada sirve la tanta seguridad que haya en nuestro servidor. Por ahi anda un codigo en java que cifra y manda la clave ya cifrada desde la computadora del usuario (un hash md5) y obviamente hay que hacer nuestra amada e irreconocible y confundible sopa de bytes para enviarlos desde la pc del usuario en cuestion a nuestro servidor. De esta manera los "mirones" o peor aun los osos hormigueros "snifers" no sabran que hacer con nuestra sopita, jijiji.

7.- Y finalmente, hay que recomendar o forzar, mejor aún, a que nuestros usuarios utilicen tanto letras minisculas como mayusculas, numeros y algunos simbolos especiales (obviamente en sopa "mezclados" jejejeje) para sus claves. Esto permitira generar hashes más robustos y dificiles de "romper" por fuerza bruta.

Saludos desde México.
Daniel Solís.
DESISCOM... Milenio!

MD5-Rainbow tables

Existen bases de datos, que apartir de un HASH se puede obtener el string original sin cifrar, sobre todo si la password es una frase comun como "qwerty" o "123456" googleando se encuentra mucho.

RE: Desencriptar

Un hash no es un cifrado, así que no se puede descifrar. Se puede buscar una colisión, es decir una palabra que produzca el mismo hash, que incluso por casualidad podria ser la misma. Si has utilizado una clave debil, un ataqe de diccionario puede recuperar la clave inicial.

Por cierto desencriptar significa sacar de la cripta. Prefiero descifrar, que es aplicar el cifrado inverso para recuperar el mensaje original. Desencriptar es un anglicismo.

Aqui en esta direccion esta

Aqui en esta direccion esta un encriptador facil de usar :P
http://www.unidadlocal.com/?x=encriptarcodigohtml

sistema

hola bienvenido a sistema

Sistema "super" seguro

Yo intento asegurarme el sistema de encriptación metiendo la función md5 dentro de una sha1. Soy algo novato todaví­a con php.

$variable_encriptada=sha1(md5($mi_variable));

Así­ que, a los expertos...¿Vale la pena utilizar este mí©todo? ¿O se trata de una estupidez?

Quizas es trabajar de mas

No soy el mas versado en este tema, soy solo un usuario basico de PHP, pero creo que crear un hash sha1 a partir del hash md5 es trabajo de sobra.

Como se dijo mas arriba, el md5 es un hash unidireccional por lo que la unica forma de romperlo es mediante fuerza bruta. Eso si, hay que tener cuidado. Aun cuando el hash destruye el mensaje y crea un hash igualmente fuerte con una contraseña de un caracter que con un mensaje de 256 caracteres, no hay que confiarse y poner una contraseña obvia porque seguira siendo vulnerable a un ataque de diccionario. Si ese fuera el caso, no hay codificacion que sirva: no importa si la almacenas como texto plano, como md5, como sha1 o como sha1 de md5 (o md5 de sha1), un ataque de diccionario la rompe facilmente.

Ahora, si alguien fuera a obtener la contraseña encriptada mediante un exploit o algun otro mecanismo que permita "robarse" la informacion de la base de datos, el hasheo md5 provee suficiente proteccion contra un ataque de fuerza bruta. Ante la poco probable eventualidad que alguien rompa el hash para una contraseña determinada, haberla re-hasheado provee un delta extra de proteccion al hacer que el atacante tenga que invertir tiempo extra en romper el primer hash y luego el segundo. En un buen dia, eso podria significar mucho mas tiempo de procesamiento que el que el atacante promedio esta dispuesto a invertir.
Personalmente he dejado de usar md5 como metodo de hashing debido a que hay sitios en internet que se dedican a generar listas de hashes (con texto plano aleatorio como argumento de entrada) con la esperanza de que ese listado contenga algun hash que puedan llegar a querer revertir. Podria pasar lo mismo con sha1 (aunque entiendo que sha1 genera un hash mas fuerte y por ende requiere mas tiempo atinarle por fuerza bruta), por lo que uso sha1 en lugar de md5

Si te preocupa en demasia la seguridad de tus claves, puedes hacer un doble md5, doble sha1 o, como propones, mezclar ambos. Vas a poder dormir mejor en las noches, aunque la probabilidad que vayas a necesitarlo es minima. (es mucho mejor que en tus sistemas fuerces a los usuarios a tener claves fuertes para reducir la probabilidad de exito en un ataque de diccionario o por fuerza bruta). Como digo, quizas es trabajar de mas, quizas no. Pero si ya lo tienes hecho y el footprint de memoria en tu servidor es bajo, no pierdes nada con dejarlo asi.

Para alguien que preguntaba un par de posts mas arriba como recuperar las claves, lamentablemente con md5 o sha1 no se puede. Si necesitas implementar un sistema que tenga la posibilidad de recuperar contraseñas olvidadas mediante una pregunta secreta o algo por el estilo, te sugiero que ademas de almacenarlas hasheadas para el sistema de autentificacion, almacenes una copia aparte (definitivamente en otra tabla y ojala en otra base de datos, con otro usuario SQL si fuera posible) pero en lugar de hashearla la cifres con la funcion crypt() de php. La forma en que lo hago yo es la siguiente:

*establezco dos bases de datos, una (llamemosla "web") que es accesible por un usuario sql ("web_user"), donde almaceno las tablas que utiliiza el sitio web incluyendo la que contiene los datos de mis usuarios (incluyendo un campo "username" y un campo "password" hasheado sha1); y otra (llamemosla "interna") con un usuario ("interna_user") que en una tabla almacena un listado con los mismos usernames asociados a la contraseña cifrada con crypt().

*La segunda base de datos solo es accesible en caso que alguien busque recuperar su contraseña, en caso contrario no se toca nunca.

*La bondad que tiene crypt es que es reversible. Entonces, si alguien necesita recuperar su contraseña, revierte el crypt y envia por correo electronico la contraseña.

¿por que usar dos bases de datos y dos usuarios distintos? Quizas es paranoia, pero ante la eventualidad que una inyeccion sql o un ataque XSS del que no pueda defenderme bien permita a un atacante rescatar la base de datos web (la unica accesible desde el sitio), el atacante solo va a recuperar los datos hasheados unidireccionalmente, pero yo sigo teniendo la posibilidad de recuperar la contraseña de un usuario olvidadizo. De esta forma no sacrifico la seguridad que me da sha1 ni tampoco la reversibilidad.

saludos!

El MD5 aplica una función

El MD5 aplica una función hash unidireccional,y al ser hash unidireccional el MD5 destruye el mensaje, solo tiene una dirección, no hay vuelta atras.

Desencriptar

Supongamos que deseo recuperar la contraseña original para una funcionalidad de recordar la contraseña al usuario. ¿Cómo lo desencripto?

No puedes, MD5 es una

No puedes, MD5 es una sumatoria... lo que puede generar colisiones, es decir... para una clave sin cifrar puede existir un mismo valor MD5, por lo tanto es inutil realizar este proceso!

Enviar un comentario nuevo

El contenido de este campo se mantiene como privado y no se muestra públicamente.
  • Las direcciones de las páginas web y las de correo se convierten en enlaces automáticamente.
  • Etiquetas HTML permitidas: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Saltos automáticos de líneas y de párrafos.

Más información sobre opciones de formato