Programación en castellano
Inicio > Taller Java > Internet > Enviando passwords de forma segura con MD5 y PHP3
-Artículos

Enviando passwords de forma segura con MD5 y PHP3

1 . El algoritmo MD5
2 . El formulario de Login
3 . El script en PHP3

Artículo cedido por La página de Alfredo Reino.

El algoritmo MD5

El algoritmo MD5 es una funcion de cifrado tipo hash que acepta una cadena de texto como entrada, y devuelve un numero de 128 bits. Las ventajas de este tipo de algoritmos son la imposibilidad (computacional) de reconstruir la cadena original a partir del resultado, y tambien la imposibilidad de encontrar dos cadenas de texto que generen el mismo resultado.

Esto nos permite usar el algoritmo para transmitir contraseñas a traves de un medio inseguro. Simplemente se cifra la contraseña, y se envia de forma cifrada. En el punto de destino, para comprobar si el password es correcto, se cifra de la misma manera y se comparan las formas cifradas.

El ejemplo que vamos a ver ahora, se implementa un sistema de formulario de login y un script hecho en PHP3 que comprueba su validez.

Para ello, utilizamos la implementación de MD5 en JavaScript de Paul Johnston.

El formulario de Login

El siguiente documento en HTML contiene un formulario en el que el usuario introduce su nombre de usuario y una contraseña. Cuando se pulsa el botón de enviar, se añade al password un numero aleatorio, y todo ello se cifra usando el algoritmo MD5.

A continuación, el numero aleatorio, y el resultado del MD5, se introducen en elementos tipo "Hidden" en el formulario, y se envia todo a un script escrito en PHP3 que verifica el acceso.

Formulario de login
<html><head><title></title>
<script language="JavaScript" src="md5.js"></script>
<script language="JavaScript">
numero = Math.random().toString();

function calculaMD5() {
var pw = document.forms["login"].elements["password"].value
pw += numero
return calcMD5(pw)
}

function enviaMD5(hash) {
document.forms["login"].elements["cifrado"].value = hash;
document.forms["login"].elements["numero"].value = numero;
document.forms["login"].submit();
}
</script>
</head>

<body>
<form action="auth.php3" method="POST" name="login">
Usuario: <input type="Text" name="usuario"><br>
Password: <input type="Password" name="password"><br>
<input type="Hidden" name="cifrado" value="">
<input type="Hidden" name="numero" value="">
<input type="Submit" value=" Login " onClick="enviaMD5(calculaMD5())">
</form>
</body></html>

El script en PHP3

PHP3 es un lenguaje de server-side scripting, como pueda serlo el ASP, ColdFusion, etc. En este ejemplo se ha usado PHP3 porque ya lleva una implementación del algoritmo MD5. Además, PHP3 es gratuito y open source. Para más información, lo mejor es visitar http://www.php.net/

Igualmente se podría haber utilizado ASP, utilizando la misma implementación del MD5 que vimos antes, y escribiendo el script en JSCript.

Básicamente, el script extrae el password para el usuario correspondiente (la función passwordUsuario(), no está detallada en este texto). A continuación, le añade el número aleatorio que recibe del formulario, aplica el algoritmo MD5, y lo compara con el valor del password cifrado que recibe del formulario.

Instalación de Apache/Php
<html><head><title></title></head>
<body>

<?
$password = passwordUsuario($usuario);

$serverpassword = strtolower(md5($password.$numero));
$clientpassword = strtolower($cifrado);

if ($serverpassword==$clientpassword)
{ print "<p>Correcto!"; }
else
{ print "<p>Acceso denegado!"; }
?>

</body></html>
 

Últimos comentarios
Últimos 5 comentarios

http://www.posicionempresarial.es/ (29/05/2008)

Por
Me parece una aplicacion muy sencilla, porque el php ya por estar trabajando en el servidor es seguro

http://www.posicionempresarial.es/
http://www.d-w-m.es/

Para Luis (23/11/2007)

Por
Creo que es una vergüenza que alguien que parece de seguridad y que seguro que aprecia la informática diga: \\\"dejad de reinventar la rueda\\\". Si por algo la informática es tan rica hoy en dia es justo por \\\"reinventar la rueda\\\". Si tienes conocimiento de la evolución de la informática, sabrá que han surgido lenguajes como php, java habiendo cgi + C, o C respectivamente. \\\"Reinventaron la rueda\\\", pero haciendola válida para todos los coches y que se pudiera trabajar con ella más fácilmente.
Bien, dicho esto, solo apuntar que este script no sirve de nada porque un sniffer tendria los datos del hash y del numero, con lo que no te sirve.
Aqui el proposito es lograr una conexion segura sin htpps (claro que es lo ideal, pero paga tu eso).
Desde luego enviar la contraseña encriptada en md5 en un gran paso para que un sniffer no sepa la contraseña original, sino solo el hash.
Ahora, lo del numero es una tonteria porque un sniffer tambien te va a coger el numero. Y coge y envia el has con el numero ese y listo.
La cuestion seria obligar al que envia la información a usar un numero en la codificación. Asi, si un sniffer lo intenta, el servidor no le hará caso ya que el numero que le manda el usuario no es el numero que el servidor queria.
El problema de esto seria que habria que almacenar los numeros en alguna base de datos (mysql), y luego borrarlos. Habria que asociarlo con una id o con su ip, da lo mismo. La cuestion es que el servidor imponga un numero al azar.
Luis, este metodo que progongo supongo que si que es seguro. El sniffer solo tiene un hash o varios hash con un numero que el no sabe cual es. Si esto lo hacemos con numero del 1 al 10000 o mas, tendria que almacenar cientos de hashes y hacerlo en el tiempo que se está autentificando el usuario.
Es decir, que estamos ante un sistema seguro!

Pequeña gran ignorancia (12/11/2007)

Por
Tu respuesta titulada \"pequeña gran contradición\" no es tal, y sólo es fruto de no saber cómo funcionan las funciones hash de una sola vía.

Lo que el autor ha querido decir con eso es que, conociendo un resumen criptográfico (hash) de una cadena, generar otra que tenga el mismo resumen (colisión) es difícil. Y dicha dificultad reside en la cantidad de hashes diferentes que puede generar la función, que en el caso de MD5 es de dos elevado a 128. Si una persona conoce un resumen criptográfico y quisiera conocer cuál es la cadena que ha dado lugar a ese hash, necesitaría en el peor de los casos 2 elevado a 128 intentos para conseguirlo peeeero, eso no le garantiza obtener la misma cadena (lo cual es casi imposible porque es de una posibilidad frente a infinito) sino que obtendrá otra cadena que produce el mismo hash. No obstante, a efectos de la autenticación sería válido ya que el servidor se basa en el hash obtenido, no en la cadena que lo ha generado.

En resumidas cuentas: El autor ha escrito mal el texto al hablar sobre la \"imposibilidad de encontrar dos cadenas de texto que generen el mismo resultado\". Sí que se puede, y el caso peor está calculado. Lo que sucede es que es muy difícil (cada día menos debido a los ordenadores más rapidos). Por otro lado, cometes un error al tragarte este pastiche sobre autenticación y seguridad.

Pequeña gran contradiccion (25/10/2007)

Por
Hola, me parece bárbaro el artículo y muy bueno el ejemplo, pero me gustaría que me expliques un poco la parte en que escribes:

-“ y también la imposibilidad de encontrar dos cadenas de texto que generen el mismo resultado.”

Te contradices con:

-“ para comprobar si el password es correcto, se cifra de la misma manera y se comparan las formas cifradas.”

¿Si es imposible que de dos cadenas de texto se generen el mismo resultado, como hago para comparar la clave enviada y la que ya esta almacenada en el host?

¿ah? L

Saludos.

Es una tontería de método (17/10/2007)

Por
En respuesta a Loksly , tu solución es igual de inútil. Da lo mismo que el nº aleatorio se genere en el cliente o en el servidor. La cuestión es que es enviado y puede ser interceptado por un tercero que esté escuchando la red. Luego sólo tiene que repetir lo que tenía previsto hacer el cliente y hacerse pasar por él.

Mirad (y esto va para todos), las técnicas basadas en cifrar simétricamente a base de secretos, en donde dichos secretos viajan por la red, no tienen sentido.

Toda esta tontería de usar funciones hash en el lado del cliente no protege contra nada. El propio protocolo HTTP incorpora la posibilidad de usar MD5 para cifrar los passwords en el navegador (la famosa \"autenticación digest\"). Y en la especificación se deja claro que ese método es una medida de seguridad no confiable.
Si realmente queréis seguridad dejad de reinventar la rueda (y lo que es peor, sin saber) y centraos en los certificados digitales con su correspondiente respaldo de terceros (Verisign y cia). El resto son ganas de perder el tiempo y, lo que es peor, de crear una falsa imagen de seguridad.
 
Tienda
Patrocinados
 

Copyright © 1999-2007 Programación en castellano. Todos los derechos reservados.
Formulario de Contacto - Datos legales - Publicidad

Hospedaje web y servidores dedicados linux por Ferca Network

red internet: musica mp3 | logos y melodias | hospedaje web linux | registro de dominios | servidores dedicados
más internet: comprar | recursos gratis | posicionamiento en buscadores | tienda virtual | gifs animados