en: Programacion
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.
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.
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);
}
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
}
}
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.
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
13 Respuestas a Howto encriptar passwords en la base de datos
Anónimo
1 de Octubre de 2006 a las 6:44 am
Supongamos que deseo recuperar la contraseña original para una funcionalidad de recordar la contraseña al usuario. ¿Cómo lo desencripto?
manu
1 de Octubre de 2006 a las 6:49 am
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.
Anónimo
1 de Octubre de 2006 a las 8:21 am
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?
Anónimo
14 de Octubre de 2006 a las 7:15 pm
hola bienvenido a sistema
Anónimo
6 de Febrero de 2007 a las 1:34 pm
Aqui en esta direccion esta un encriptador facil de usar
http://www.unidadlocal.com/?x=encriptarcodigohtml
Anónimo
30 de Septiembre de 2007 a las 3:19 am
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!
pit
11 de Noviembre de 2007 a las 9:04 am
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.
Daniel Solís
16 de Mayo de 2008 a las 9:47 pm
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!
Otto Jiménez
7 de Enero de 2008 a las 11:55 am
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!
Gustavo
15 de Enero de 2008 a las 8:27 am
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.
sonic22
29 de Mayo de 2008 a las 2:05 am
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
Miguel
22 de Septiembre de 2008 a las 5:56 am
Independientemente de que se encripte o no la contraseña, el primer paso según mi opinión es escoger una que cumpla unos criterios básicos de seguridad. La podemos crear nosotros mismos aporreando el teclado, pero teniendo en cuenta que cuantos mayor número y variedad de carácteres, más seguridad tendremos. También hay páginas que te las generan automáticamente según los criterios que quieras (yo las uso mucho para mis desarrollos): http://www.safepasswd.com, o su versión en español http://www.clavesegura.org.
¿Has olvidado tu contraseña? Cómo desvelar asteriscos y recuperar contraseñas | ceslava - Diseño y Formación
18 de Octubre de 2009 a las 11:05 am
[...] contraseñas se vayan guardando en una base de datos MySQL. Normalmente estas contraseñas están encriptadas para mayor seguridad con el algoritmo MD5 y no se pueden recuperar o al menos no [...]