Archive for the ‘tecnica’ Category

AS3 Arrays (part II)

Miércoles, Agosto 29th, 2007

Como os prometí, voy a poner algun ejemplo más de los nuevos metodos del array en Actionscript 3. Particularmente interesantes son:

map: Ejecuta la funcion en cada uno de los elementos y crea un nuevo array con el resultado. Esto es particularmente útil cuando necesitas hacer una transformación sobre todos los elementos del Array como convertirlos en mayusculas/minusculas, cambiar espacios por guiones o cosas mas complicadas con objetos. Posiblemente es de las novedades que más utilize.

filter: Ejecuta la funcion en cada uno de los elementos para determinar si deben de aparecer en el nuevo Array. Como su propio nombre indica sirve para realizar un filtro determinado sobre los elementos.

Muy interesante tambien la posibilidad de ir combinandolos, el siguiente ejemplo pone en mayusculas la primera letra de los elementos en un Array de Strings, desecha los elementos que no tengan mas de una palabra y los muestra en pantalla.

Actionscript:
  1. <code>
  2. var items:Array = ["turn on the bright lights","antics","our love to ADMIRE"];</code>
  3.  
  4. function capitalize(item:String,index:int,arr:Array):String
  5. {
  6. return item.charAt(0).toUpperCase() + item.substring(1).toLowerCase();
  7. }
  8. function multipleWords(item:String,index:int,arr:Array):Boolean
  9. {
  10. return item.split(" ").length&gt;1;
  11. }
  12. function render(item:String,index:int,arr:Array):void
  13. {
  14. var txt:TextField = new TextField();
  15. txt.text = item;
  16. txt.y = index*20;
  17. txt.width = 200;
  18. stage.addChild(txt);
  19. }
  20. items.map(capitalize).filter(multipleWords).forEach(render);

Genial, ¿no?

Aqui enumero la lista de estos nuevos métodos para que les hecheis un vistazo:

every:
Sirve para determinar si todos los elementos de un array cumplen un determinado criterio o condicion
some:
Parecido a every. En este caso determina si alguno de los elementos lo cumplen
filter:
Crea un nuevo array filtrando los elementos
forEach:
Ejecuta una función por cada uno de los elementos
filter:
Crea un nuevo array filtrando los elementos con la función dada
map:
Crea un nuevo array esta vez transformando los elementos con la función

Bastante útiles todos como podeis ver... ;)

AS3 Arrays: ¿Quién necesita bucles?

Jueves, Julio 26th, 2007

Una cosa que de la que no he oido hablar sobre AS3 es las nuevas caracteristicas de la clase Array, si, nuestro antiguo compañero de andanzas... Que yo cuente tiene por lo menos 7 nuevos métodos que me parecen muy muy interesantes. Tanto que podría decir que usandolos no volveras a escribir un bucle que recorra un Array. Y eso, teniendo en cuenta que el 90% de los bucles que normalmente se escriben se utilizan con Arrays, es mucho decir.

La primera bendición llega con el nombre de indexOf(), seguro que mas de una vez lo habeis utilizado con la clase String, pues básicamente funciona igual solo que busca en un elemento en un Array.

Actionscript:
  1. // Busco y elimino el elemento "dos"
  2. var numeros:Array = ["uno","dos","tres","cuatro"];
  3. numeros.splice( numeros.indexOf("dos"), 1);

Por fin se puede buscar algo dentro un array manteniendo la dignidad, sin la necesidad de un embarazoso bucle :_)

Pero ahi no acaba todo, dados los nuevos closures, se han añadido a la clase Array unos metodos que cogen funciones como parametros y hacen cosas muy utiles. El mejor ejemplo, el forEach, ¿Cuantas veces has hecho un bucle para crear MovieClips por cada uno de los elementos? Me referia a cúantas al dia... ;)

Actionscript:
  1. var nombres:Array = ["uno","dos","tres","cuatro"];</code>
  2.  
  3. function mostrar(item:String,index:Number,array:Array):void{
  4. var tx:TextField = new TextField();
  5. tx.text = item;
  6. tx.y = index*20;
  7. addChild(tx);
  8. }
  9.  
  10. nombres.forEach(mostrar);

Como veis el metodo forEach coge como parametro una funcion y la ejecuta una vez por cada elemento del Array pasandole como argumento el propio elemento entre otras cosas. Realmente me encanta... Más sobre esto en próximos posts.

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 ;)