Lógica Alternativa

'¿Otro blog de informática? … Todavía no' .- Cuaderno de bitácora de Miguel R. Esteban

Ir al contenido
  • Inicio
  • Mi CV
  • Mapa del sitio
Lógica Alternativa

Securización de formulario de acceso con SHA-1

sha1Muchas veces las aplicaciones web no tienen acceso por ssl (https) y suelen tener un formulario de ‘login’ de usuario y contraseña.

Esto quiere decir que información sensible como la contraseña se transmite en texto claro y que sea relativamente fácil que terceros pueden tener acceso a ella. Por ejemplo esnifando el tráfico si el usuario se conecta con una wifi abierta.

Lo que presento a continuación es una manera sencilla de securizar la contraseña utilizando el algoritmo hash sha-1. Por simplicidad este ejemplo lo he hecho en PHP, pero no tiene complicación hacerlo en Java. He utilizado también la librería de javaScript PHP.js que no conocía pero ‘me ha gustado su lógica‘ 🙂

Bueno este es el problema y esta es la solución que propongo. Al lío…

¿Qué es una función hash?. Es una función criptográfica de un sólo sentido. A grandes rasgos es:

Del valor obtengo el hash => Del hash NO puedo obtener el valor.

Además me asegura que si el valor cambia en un carácter o en un bit, el hash obtenido es totalmente diferente.

Tengo que decir que el algoritmo sha1 es matemáticamente reventable con ataques de fuerza bruta del rango 263 operaciones. Una barbaridad que hace que para el propósito que nos ocupa el uso del sha-1 sea más que suficiente.

Esta es la idea. Desde el navegador se genera con javascript el hash del resultado de concatenar la contraseña y una parte aleatoria (que se guardada en sesión). Esta es la cadena que viaja y no la contraseña. Cada vez será diferente, porque se ha generado con una parte aleatoria, y será inteligible, no se sabrá con que cadenas se ha creado al ser un hash. Para comprobar el acceso, en el servidor se realiza el mismo calculo y se comparan las cadenas.

Se ve mejor en un ejemplo, lo tienes disponible en:

https://github.com/logicaalternativa/ejemplosPHP/tree/master/loginsha1

Son dos ficheros. El index.php, que tiene el formulario de acceso y el javaScript del cáculo del hash, envía los datos a resultado.php. Este  obtiene a partir del usuario la contraseña, vuelve a calcular el hash y compara las cadenas.

Index.php

(Código entero del script)

Lo primero que se hace es en PHP crear la cadena aleatoria y almacenarla en sesión:

 PHP | 
 
 copy code |
?

1
// Se calcula la cadena aleatoria
2
$tokenSesion = rand(1,9) * 1000000 + rand(0,10) * rand(0, 10000) ;
3
// Se guarda en sesión
4
$_SESSION['tokenSesion'] = $tokenSesion;

Código 01

La línea 2 es una manera de calcular un número aleatorio. Se consigue un valor entre 1000000 y 9999999. Puedes utilizar tu propio método.

En la línea 3 se guarda el valor generado en sesión que luego se usará en resultado.php donde se recogen los datos del formulario de acceso.

El formulario de acceso además de los campos de usuario y contraseña tiene el campo oculto ‘token‘.

 HTML | 
 
 copy code |
?

1
<form name="formularioAcceso" method="post" action="resultado.php" onSubmit="return acceder()">
2
   <input name="token" type="hidden" value="">
3
   ...
4
   <input name="usu" type="text" id="usu" value=""> </td>
5
   ...
6
   <input name="contra" type="password" id="contra"></td>

Código 02

El quit de la cuestión está en la función javaScript acceder(). Está función se llama desde el evento onSubmit del formulario

 Javascript | 
 
 copy code |
?

1
function acceder(){
2
   var contra = document.forms.formularioAcceso.contra.value + '';
3
   var token= sha1('<?=$tokenSesion?>' + contra);
4
   document.forms.formularioAcceso.contra.value = '';
5
   document.forms.formularioAcceso.c.value = token;
6
   return true;
7
}

Código 03

Explico un poco la función. Se obtiene el valor de la contraseña tecleada por el usuario en la línea 2.  En la 3 se concatena el valor aleatorio generado en PHP con la contraseña del usuario, y se hace el sha-1. Después se ‘borra’ la contraseña para que no viaje, colocando la cadena vacía en el campo del ‘contra’ formulario. Finalmente se coloca el token calculado en el campo oculto ‘token’ que tiene el formulario.

Para hacer el cálculo de la función sha-1, he utilizado la librería JavaScript PHP.js.

Esta gente ha implementado en JavaScript las funciones disponibles en PHP. Sencillo y genial, lógica alternativa. Así que si tienes un problema en JavaScript y  piensas ‘… esto en PHP lo haría en dos «pataas«…’, no lo dudes esta es tu librería. Su repositorio tiene la misma estructura que en el índice de funciones del manual de PHP así que son fáciles de encontrar.

He incluido las librerías en el head

 HTML | 
 
 copy code |
?

1
...
2
<script language="JavaScript" src="https://raw.github.com/kvz/phpjs/master/functions/xml/utf8_encode.js"></script>
3
<script language="JavaScript" src="https://raw.github.com/kvz/phpjs/master/functions/strings/sha1.js"></script>
4
....

Código 04

Para que sea más didáctico he incluido directamente las librerías de su repositorio. Pero lo lógico es bajarlas a tu proyecto, los ficheros js están disponibles en el ejemplo. Es necesario incluir la función utf8_encode.js porque la de sha1 depende de ella (vienen indicado en la cabecera de la función)

resultado.php

(Código entero del script)

Este es el PHP que se encarga de recibir el usuario y el token sha-1.

 PHP | 
 
 copy code |
?

1
   $usuario = $_REQUEST[ 'usu'];
2
   $token = $_REQUEST['token'];
3
 
4
   $tokenSesion = $_SESSION['tokenSesion']; 
5
   $_SESSION['tokenSesion'] = null;

Código 05

Obtiene el usuario y el token del formulario enviado. En la línea 4 se obtiene de sesión la cadena aleatoria con la que se ha generado el hash. Por seguridad en la línea 5 se borra de sesión.

A partir del usuario que se ha enviado en el formulario se obtiene la contraseña

 PHP | 
 
 copy code |
?

1
// Usuarios 
2
$claseAcceso = new AccesoDummy();
3
// Se obtiene la contraseña del usuario
4
$contra = $claseAcceso->dameContrasena( $usuario );
5
// Se calcula el token
6
$tokenCalculado = sha1( $tokenSesion.$contra ); 

Código 06

La clase ‘AccesoDummy‘ es una implementación muy tonta que se ha hecho para este ejemplo. Aquí cada uno lo hará a su manera. Lo importante es obtener la contraseña del usuario por medio de su identificador.

En la línea 6 lo que se ha hecho es obtener otra vez el token de acceso pero esta vez en el servidor. Ahora sólo queda comparar las dos cadenas para ver si está todo correcto y darle acceso al usuario.

 PHP | 
 
 copy code |
?

1
if ( isset( $contra )  &&
2
      $token == $tokenCalculado ){
3
   $texto = 'Acceso correcto';
4
   ... 
5
} else {
6
   $texto = 'Acceso incorrecto';
7
   ... 
8
} 

Código 07

… Y el resultado

Puedes probar una demo en:

http.http://localhost:8080/etc/ejemplos/php/loginsha1

pantallazo1_sha1PHPpantallazo2_sha1PHP

Si lo probáis varias veces veréis que, siendo el acceso correcto con el mismo usuario, el token siempre cambia.

Espero que os sirva de ayuda…

M.E.

Esta entrada se publicó en JavaScript, PHP y está etiquetada con acceso, JavaScript, login, PHP, securizar, SHA-1 en 19 abril, 2013 por Miguel R. Esteban Martín.

Navegación de entradas

← Networking, networking (Java) Securización de formulario de acceso con SHA-1 →
[RSS]  RSS de las entradas

Entradas recientes

  • Notas sobre aprendizaje por refuerzo
  • Diapositivas de la charla de Commit Conf
  • Futuros y promesas,… y también monadas. Implementando el patrón
  • Actores tipados, Akka por ejemplos
  • Akka por ejemplos. Sobre supervisión, bus de eventos, …

Sobre el autor

[Sobre el autor] Mi nombre es Miguel Rafael Esteban Martín. Llevo más de 20 años trabajando como desarrollador  y  arquitecto  de software en diferentes empresas, lenguajes de programación y plataformas.
En este blog hablaré sobre programación y tecnología e intentaré hacerlo de manera clara y amena.
Actualmente trabajando como programador de software en Darwinex.
Más sobre mi en el enlace Mi CV

Contacto
[correo electrónico][Perfil en LinkedIn][Perfil en Twitter][Perfil en GitHub]

Categorías

  • Android
  • APIs
  • Control de la configuración
  • Criptografía y certificados
  • General
  • Inteligencia artificial
  • Java
  • JavaScript
  • La Nube
  • Patrones
  • PHP
  • Programación
  • Sistemas operativos
Licencia de Creative Commons
Lógica Alternativa by Miguel Rafael Esteban Martín is licensed under a Creative Commons Reconocimiento-NoComercial 3.0 Unported License.