Archive for the ‘criptografia’ Category

Flash y criptografía: Técnica de ocultación de información en cliente.

Martes, Agosto 30th, 2005

Otra vez de nuevo por aquí con una técnica que creo que muchos pueden encontrar interesante. En un trabajo reciente para un cliente, este quería colgar en una web en Flash unos archivos que solo se pudieran descargar con password. Hasta aquí nada peculiar excepto por el hecho de que el servidor no soportaba lenguaje de servidor, además pedirlo solo para eso me parecía exagerado. Así que como últimamente he estado trabajando un rato con el tema de encriptación le he estado dando vueltas para conseguir un sistema que aunque no fuese infalible (ninguno lo es) evitase los casos mas probables de ataque, como la decompilación del SWF e incluso temas mas complicados como algún sniffer.

Seguro que alguno me cuenta que este sistema ya lo conocía, que es trivial, pero la criptografía es un tema de lo más oscuro para muchos. Vamos, lo era para mí hasta que me tuve que meter de lleno por un proyecto que requería especial tratamiento en la seguridad.

Por explicarlo rápidamente y muy por encima digamos que hay 2 tipos de algoritmos:

  • Los de vía única, no reversibles, comúnmente llamados algoritmos de hash, que tienen 2 características que son muy útiles:
    • Una vez cifrado el texto, no se puede descifrar, no hay vuelta atrás.
    • Y que es prácticamente imposible que usando dos textos diferentes se obtengan el mismo hash. Los más conocidos son MD5 y SHA-1.

    Actualización: Xabi Beumala me comenta:

    Los algortimos reversibles se separan en dos grandes grupos, los simétricos y los asimétricos. En los simétricos la llave es la misma en ambos extremos (encrypt y decrypt), en los asimétricos tienes dos llaves una deshace a la otra.

  • Los reversibles, seguramente los mas conocidos por todos. Tienes una palabra clave que usas para cifrar el texto y esa misma clave sirve para revertir el texto. Hay muchos de este tipo, pero los más conocidos son los RSA y AES.

Antes de comenzar os tenéis que bajar unas clases de crypto que resuelvan la parte engorrosa del asunto: Implementar los algoritmos. Os recomiendo las ASCrypt que tiene todo lo que necesitamos. En el ejemplo usaremos estas, aunque hay otras como ActionCrypt

Para poner en práctica esta técnica que os cuento no nos valdría solo con este ultimo tipo ya que de alguna manera deberíamos incluir la clave en los datos del SWF o se tendría que trasmitir desde el servidor lo que haría el sistema bastante débil. Necesitamos una combinación de los dos.

El escenario es el siguiente. Pensamos en una palabra clave, esta es la que le vamos a dar a los usuarios que queremos que tengan acceso. Pongamos que es "privado". OK

Previamente calculamos el Hash usando SHA1 (por ejemplo) y copiamos el hash que hemos obtenido, que seria "7e4231b4e1b8534ea5106bf821f0bb324987c567" y en Flash simplemente comprobamos si el usuario es válido con un simple if:

Actionscript:
  1. import com.meychi.ascrypt.*;
  2. var logged:Boolean = false;
  3. var key:String;
  4. function validate(pass:String):Boolean{
  5. if(SHA1.calculate(pass)== "7e4231b4e1b8534ea5106bf821f0bb324987c567"){
  6. logged = true;
  7. key = pass;
  8. return true;
  9. }
  10. return false;
  11. }

Lo interesante aquí es que da igual que vean el texto cifrado (hash) porque no es posible revertirlo para ver la clave original :) así que aunque vean el código fuente es prácticamente imposible obtenerla.

Fijaros también que guardamos la clave que ha introducido el usuario en la variable "key", esta la vamos a utilizar en el paso siguiente. Ahora imaginaros que la url que queremos ocultar es: "/ficheros/documento.pdf". Ahora utilizaremos un algoritmo reversible, un AES, también conocido como Rijndael. De nuevo generamos el texto cifrado para esa url usando como clave "privado" la misma que hemos hasheado con el SHA1 y nos devolverá lo siguiente: "3e3b9304a675c7fb24be775d4aee65962118be8080270e618204093773374004", perfecto, de nuevo nos vamos a Flash y utilizamos la variable "key" donde hemos almacenado la que ha introducido el usuario para desencriptar ese churro y obtener la url original:

Actionscript:
  1. var codec:Rijndael = new Rijndael(192, 128);
  2. function decryptfile(crypto:String):String{
  3. return codec.decrypt(crypto, key, "ECB");
  4. }
  5. descargar.onRelease = function(){
  6. if(logged){
  7. getURL(decryptfile("3e3b9304a675c7fb24be775d4aee65962118be8080270e618204093773374004"),"_blank");
  8. }
  9. else{
  10. trace("No permitido");
  11. }
  12. }

De esta manera ya tenemos protegido el nombre del fichero. Y es prácticamente imposible obtenerlo sin conocer la clave. Creo que winzip, winrar .etc. utilizan un sistema parecido para proteger los ficheros.

Este sistema tiene algunas pegas, una de ellas es el hecho de la clave se tiene que proporcionar previamente al usuario de alguna manera, ese método puede ser inseguro (como el email común) y ahí estaría el talón de Aquiles del sistema. Otro inconveniente es que el hecho de cambiar la clave obliga a generar de nuevo el hash y todos los textos cifrados, pero esto se podría aliviar manteniéndolos en un XML externo y actualizándolo cuando esta cambiase. Incluso se podrían cargar diferentes basándose en un nombre de usuario o email.

Bueno, espero que os sea útil esta técnica. Admito todo tipo de comentarios al respecto, no soy un experto en criptografía ni mucho menos, pero creo que el sistema en sí tiene una fiabilidad bastante alta.

Aquí os cuelgo el fichero de ejemplo y un generador de claves para crear el hash y las urls cifradas. Merece la pena que leáis sobre el tema, si quitas los detalles de implementación, el resto es bastante interesante ;)