jueves, 25 de marzo de 2010

Introduccion a la criptografia, con Python: ARC4 (I)

La idea es hacer una serie de posts que cubran algunos de los algoritmos de criptografia mas usados, por lo menos uno decifrado simetrico (como ARC4) , otro de cifrado asimetrico (como RSA) y uno de hash (como MD5), vamos alla....

ARC4 (a.k.a. RC4 ) es el algoritmo de cifrado que se usa en WEP, en WPA y en SSL, entre otras cosas, y destaca por que es extremadamente sencillo y rapido... pero si no se usa correctamente no es seguro 

Mas concretamente, es un cifrado de flujo, es decir que cifra el mensaje haciendo XOR de el byte de entrada y el byte que se obtiene del algoritmo (del keystream), y que la forma de cifrar y descifrar es exactamente la misma.

El cifrado se maneja con las siguientes estructuras:
  - Dos enteros (aqui seran 'i' y 'j') que solo tendran valores del 0 al 255
  - Un array de 256 bytes (aqui sera 'S' )

La primera parte del cifrado ( el "seeding" ), tiene dos partes, la primera es llenar el array 'S' con valores del 0 al 255 (ambos incluidos), algo como:


s=range(0,256)

Y despues se mezcla un poco todo...

k
=0 for n in range(0,256): k=(k+self.s[n]+ord(clave[n % len(clave)]))%256 swap(n,k)

Swap intercambia los valores de S con los indices que se le dan...


def
swap(n,k): t=s[n] s[n]=s[k] s[k]=t

La primera parte ya esta (este es el codigo todo junto):


class
arc4: # Intercambia dos valores del array 's' def swap(self,n,k): t=self.s[n] self.s[n]=self.s[k] self.s[k]=t def __init__(self,key): # Generamos el array 's', normalmente se utilizaria un bucle para llenarlo # con los valores de 0 a 255, pero python lo hace mas facil self.s=range(0,256) k=0 for n in range(0,256): k=(k+self.s[n]+ord(key[n % len(key)]))%256 self.swap(n,k) self.i=0 self.j=0

Ahora para cifrar se extrae un byte (al flujo de bytes que se extrae se le llama keystream) por cada byte de entrada y se les hace XOR...
Para extraerlo a la variable "nuevobyte" se hace esto:


i=(i+ 1)% 256 j=(j+ s[i])% 256 swap(i,j) nuevobyte= s[(s[i]+ s[j])% 256]


Asi que para cifrar una string completa:


def
nextbyte(self): self.i=(self.i+ 1)% 256 self.j=(self.j+ self.s[self.i])% 256 self.swap(self.i,self.j) return self.s[(self.s[self.i]+ self.s[self.j])% 256] def cipherbyte(self,byte): return byte^self.nextbyte() # Aunque se usa para cifrar y descifrar... def cipher(self,text): a="" for c in text: a+=chr(self.cipherbyte(ord(c))) return a

Se utilizaria la ultima funcion (cipher) para cifrar y descifrar
Y el codigo ya esta... si lo probamos [ codigo completo: arc4.py ] :


>>> cifrador=arc4("password")
>>> text="Hola, mundo!"
>>> cifrado=cifrador.cipher(text)
>>> print cifrado
·šTo` ÙÛ 5Ä]
>>> descifrador=arc4("password")
>>> descifrado=descifrador.cipher(cifrado)
>>> print descifrado
Hola, mundo!
>>>



Como se puede ver funciona bien :)}

Como usarlo (y como no usarlo):

Como ya se dijo antes, el algoritmo funciona bien dentro de lo que cabe, pero hay que tener en cuenta unas cosas cuando se use:

Es recomendable descartar por lo menos los primeros 256 (un valor con cierto margen seria 3072 ) bytes del keystream, en el ejemplo se haria con


for
n in range(0,256):
    cifrador.nextbyte()
 antes de empezar a cifrar y


for
n in range(0,256):
    descifrador.nextbyte()
antes de  descifrar.

Esto es por que de los primeros bytes del keystream se puede extraer informacion sobre la contraseña, otra posibilidad es utilizar claves temporales, una forma de hacerlo seria enviando un texto en plano, que se añade a la contraseña, y al resultante pasarle una funcion de hash (como MD5), con esto se conseguiria que aun crackeando la clave temporal y el texto en plano añadido no se pudiera recuperar la clave original (habria que hacer un ataque de fuerza bruta sobre el hash, ya que no se pueden usar Rainbow tables por el texto añadido, que funcionaria de salt)

Por supuesto seria recomendable utilizar las dos medidas, ya que usar varias veces la misma clave (especialmente en un cifrado de flujo) es una MALA IDEA y descartar los primeros bytes supone un esfuerzo computacional muy pequeño y aumenta la seguridad.

Por ultimo, volver a recordar, NO es buena idea usar dos veces la misma clave.

Y eso es todo, hasta otra!!

Ah! y el codigo esta coloreado con pygments

El codigo fuente en Python del cifrador arc4.py

[Referencias]
RC4 en la Wikipedia

lunes, 22 de marzo de 2010

Como permitir que firefox se conecte a otros puertos

Hoy vengo con algo corto, que me pillo desprevenido, y supongo que a alguien le ayudara

Hace ya tiempo que firefox no permite conectarse a algunos puertos no estandar, como el 87, esto esta bien para evitar el HTML Form Protocol Attack [ http://www.remote.org/jochen/sec/hfpa/index.html ]

Pero esto puede resultar molesto en sitios que utilizan estos puertos para la navegacion web (como smashthestack.org ), para permitir utilizar estos puertos, entramos a about:config ( le damos a "Tendre cuidado, lo prometo" ), y buscamos "network.security.ports.banned.override", si no existe lo creamos:
boton secundario>Nuevo>Cadena
Nombre: network.security.ports.banned.override
Valor: <la lista de puertos separados por comas>

Si ya existe, hacemos doble click, y añadimos los puertos (separados por comas)


Y ya esta!, hasta otra!

Logo y colorines ( y II )

Volvemos con la segunda parte sobre Logo, con unas cuantas figuras...

La primera, para empezar es bastante facil:
to figura1 :veces :tamanho
     repeat :veces[right 360/:veces
                   repeat 360[ forward :tamanho right 1 ]
                   ]
end


Y " figura1 72 2  " resulta en ...


Fractales
Pasamos a algo mas dificil :)}

¿Que es un fractal? (segun Wikipedia)

Un fractal es un objeto semigeométrico cuya estructura básica, fragmentada o irregular, se repite a diferentes escalas.[1] Una mejor manera para comprender el comportamiento fractal de nuestro universo es considerar la siguiente definición: "Patrones que se repiten a distintas escalas".
A un objeto geométrico fractal se le atribuyen las siguientes características:[2]
Dejemos aparte todo lo de "autosimilar", "dimensiones topologicas" y demas... lo mas comprensible es que "se repite a distintas escalas" y "se define mediante un simple algoritmo recursivo", vamos a probar...

to fractal_cuadrado :long :prof
    if prof <= 0 [stop]
    repeat 4[ forward :long
                     right 90
                     fractal_cuadrado :long/(2.5) :prof-1
                   ]
end


Llamando a "fractal_cuadrado 300 5", conseguimos esto:


Veamos como funciona, y de paso como hacer que el codigo sea aplicable a cualquier figura, la idea es esta:

to fractal_cuadrado :long :prof
No necesita explicacion, declaramos la funcion fractal_cuadrado, con los argumentos long (longitud) y prof (profundidad)

if prof <= 0 [stop]

El caso base, si ya se llego al ultimo nivel de profundidad, ya se acabo

    repeat 4[ forward :long
                     right 90
                     fractal_cuadrado :long/(2.5) :prof-1

                   ]

Como se puede ver, es practicamente el mismo codigo que para dibujar un cuadrado, solo se le añade   fractal_cuadrado :long/(2.5) :prof-1  al final, lo que hace que en cada esquina repita el proceso completo, pero haciendolo mas pequeño y con menos profundidad (sino acabaria siendo infinita)

Es decir, que en cada esquina del cuadrado, se dibuja un cuadrado mas pequeño, y en cada esquina de ese cuadrado, otro aun mas pequeño, asi hasta que se alcance la profundidad maxima (a este proceso se le llama recursion)

end
Fin de la funcion

Ahora veamos como modificar el codigo para que funcione con otras figuras, el caso base no cambia...
to fractal2 :lados :long :prof
    if prof <= 0 [stop]


... asi que solo nos queda el
    repeat 4[ forward :long
                     right 90
                     fractal_cuadrado :long/(2.5) :prof-1

                   ]

De nuevo,es bastante reconocible la parte que dibuja el cuadrado (esto se explica en el otro post sobre logo), asi que...
    repeat :lados[ forward :long
                     right 360/:lados
                     fractal2 :lados :long/(2.5) :prof-1

                   ]
Solo falta el    fractal2 :lados :long/(2.5) :prof-1 ,  la unica parte que hay que cambiar es la de :long/(2.5),  el problema es que este numero (el 2.5 ) es algo arbitrario, debe ser lo suficientemente alto como para separar las figuras "que salen de las esquinas", distancia que es mayor a medida que aumenta :log, pero sin pasarse, por ejemplo :long/(2+((:lados/100)*(:lados*:lados))) servira, asi , el codigo queda

to fractal2 :lados :long :prof
    if prof <= 0 [stop]
     repeat :lados[ forward :long
                     right 360/:lados
                     fractal2 :lados :long/(2+((:lados/100)*(:lados*:lados))) :prof-1
                   ]
end


Y llamando a "fractal2  3 200 4"...
(¿A nadie le suena de algo?)

Y para ir acabando... arboles binarios!

Un arbol binario es uno que del que salen dos arboles (tambien binarios), de los que vuelven a salir dos, y ... bueno, ya cojeis la idea

to arbol_binario :long :prof :grados
    if prof <= 0 [ stop ]
    forward :long
    left :grados
    arbol_binario :long/2 :prof-1 :grados
    right :grados*2
    arbol_binario :long/2 :prof-1 :grados
    left :grados
    back :long
end


Veamos como va, se que habra a quien le aburra y lo vea claro, pero, si ese es el caso, siempre os podeis saltar la explicacion... (Esta vez voy a prescindir del codigo)

La idea basicamente es hacer que cada vez que el arbol avance, se divida en dos y repetir en cada uno de los dos el mismo proceso, para que esto se pueda hacer, ademas hay que volver a la posicion original cada vez (si, simple y rapido)

Llamando a arbol_binario 200 10 30  tenemos:



Y eso es todo con Logo!

Pero espera... esto es "Logo y colorines" !! , hace falta algo de color, volvamos a la primera imagen:


La abrimos con GIMP y usamos en los filtros Artistico>GIMPresionista, el Crosshatch, obtenemos esto:

Seleccionamos todo lo que no es el fondo, y se aplica una mezcla de Quemado, con forma Radial, con centro en el centro del circulo, el resultado:

No es gran cosa, pero tendra que valer :P
Ahora si, hasta otra!

[Referencias]
http://et.bgcbellevue.org/logo/fractals.html

miércoles, 17 de marzo de 2010

Otro huevo de pascua en Python

A parte del conocido Zen de Python ( si no lo conoces, haz "import this"), hay otros, como el que ocurre cuando haces "import antigravity" (aunque solo funciona en Python 3 ), para los que no lo puedan probar...  se abre el navegador en http://xkcd.com/353/ la traduccion:




Hasta otra!

domingo, 14 de marzo de 2010

SSH: Conexiones seguras para tod@s ( y III ) VPN's

Pues aqui esta la ultima parte de SSH: Conexiones seguras para tod@as, las VPN's, vamos alla...
[Nota]: en todo el proceso vas a necesitar privilegios de root

Preparando el terreno
Para poder utilizar un servidor SSH para hacer una VPN, tendremos que hacer algunos cambios:

El primero es cargar el modulo del kernel "tun" (si aparece al hacer lsmod|grep tun , no hace falta), esto se puede hacer con modprobe tun

Despues vamos a /etc/ssh/sshd_config y comprobamos que los parametros PermitRootLogin y PermitTunnel esten activados (yes)

Y reiniciamos el servidor SSH

Levantando la VPN

Se establece una conexion SSH  con el servidor de una forma parecida a la que se utiliza para usarlo de proxy:
ssh -w <interface local>[:<interface remota>]  [<usuario> @]<host>
Las interfaces seran las que conecten la VPN, se pueden especificar a traves de un numero (que no puede estar en uso), o "any" (para utilizar la primera "no ocupada").

[Nota]: Siempre se va a necesitar una cuenta root en el servidor (ya que se crean nuevas interfaces)

Automaticamente, se crearan interfaces tunel (del tipo point to point) en el cliente y en el servidor (por ejemplo seran tun0 y tun1, aqui para abreviar,usaremos tunC para la del cliente y tunS para la del servidor)

Pues bien, una vez creadas hay que conectarlas, suponiendo que la VPN vaya a utilizar la subred 10.0.0.0, que el servidor vaya a  utilizar la IP 10.0.0.1, y el cliente 10.0.0.9, habria que hacer:

En el cliente: ifconfig tunC 10.0.0.9 pointopoint 10.0.0.1  

En el servidor: ifconfig tunS 10.0.0.1 pointopoint 10.0.0.9

(La "formula general" seria ifconfig <interfaz tunel> <IP local> pointopoint <IP remota> )

Y ya esta, se acabo el SSH! (al menos por ahora ;)} )

[ Referencias ]
http://prefetch.net/
http://fermiparadox.wordpress.com/

martes, 9 de marzo de 2010

Logo y colorines

Hace un par de dias que estoy trasteando con Logo [ en la wikipedia ] , un lenguaje de programacion diseñado con fines didacticos y que en este caso me parece interesante por que hace muy facil dibujar cosas en la pantalla, como lo que llaman "graficos de tortuga", lo de "tortuga" es por que el cursor era representado como una tortuga y se utiliza para referirse a el (a pesar de que en programas como ucblogo no sea una tortuga, sino simplemente una flecha )

[Nota:] probablemente haya una funcion para extraer la imagen, sino siempre os queda el Imprimir pantalla (como hice yo)

[Nota:] al final dejo unos cuantos interpretes, de todas formas, si usais un sistema Unix, casi seguro que podeis conseguir el ucblogo, ya sea por synaptic, port's o su pagina web ( http://www.eecs.berkeley.edu/~bh/logo.html )

No se necesitan muchas instrucciones para utilizarlo y pasar el rato, las instrucciones "basicas" son:

Para avanzar: forward <numero de pasos> (o fd <numero de pasos> )
Para retroceder: back <numero de pasos> (o bk <numero de pasos> )
Para girar a la derecha: right <grados que se gira> (o rt <grados que se gira> )
Para girar a la izquierda: left <grados que se gira> (o lt <grados que se gira>)
Para volver a la posicion inicial: home
Para limpiar la pantalla: clean
Para repetir instrucciones: repeat <veces que se repite> '[' <Instrucciones que se repiten> ']'
Para definir una nueva funcion: to <nueva instruccion a definir> [:<argumento1>] ... [:<argumentoN>]
[instruccion] ... [instruccion] END

Finalizar una funcion antes del stop : stop
Ocultar la tortuga: hideturtle ( o ht )
Mostrar la tortuga: showturtle ( o st )
Condiciones: if <condicion> '[' <acciones> ']'


Asi que, por ejemplo, para hacer una funcion que muestre un cuadrado, escribiriamos:

   to cuadrado
      forward 50
      right 90
      forward 50
      right 90
      forward 50
      right 90
      forward 50
      right 90

   end

o lo que es lo mismo:
 

   to cuadrado
      repeat 4[forward 50 right 90]
   end

Esto dibujaria un cuadrado cada vez que se hace cuadrado con unos lados de 50 pasos

...pero como hariamos para poder elegir la longitud de los lados ?
Veamos, las variables se usan con un ':', asi que...

   to cuadrado :lado
     repeat 4[ forward :lado right 90]
   end


[Nota:]  en los dos casos se podria usar left en vez de right, como sabeis, lo importante es girar 90 grados, no importa la direccion

 Y dibuja un cuadrado cuando se llama a cuadrado <tamaño> , por ejemplo, con  cuadrado 200, dibuja un cuadrado con 200 pasos de lado

Ahora vamos a añadir algo mas, como hariamos una funcion que dibujara una figura con el numero de lados que queramos?
Seguramente ya se te haya ocurrido (no tiene demasiada dificultad precisamente :P), pero para quien no, ahi va la explicacion:

Si te fijas en la "formula del cuadrado", va asi (en pseudocodigo):
  repite 4 veces [ avanza :longitud gira 90 ]
Conclusiones:
  - Se repite el mismo numero de veces que lados hay (4)
  - Los grados que se giran son los mismos que 360 (los de una vuelta completa) entre el numero de lados (hay que empezar y acabar en el mismo punto y con el mismo angulo)

Esta seria una posibilidad
to figura :num_lados :distancia
  repeat :num_lados [ forward :distancia right 360/:num_lados]
end


Entonces, para hacer un triangulo de 100 de lado, solo habria que escribir
figura 3 100


Y para un cuadrado
figura 4 100


Y para un pentagono
figura 5 100


... creo que ya pillais la idea  :)

Vale, sigamos... si lo que queremos dibujar es un circulo, habria que hacer que de una vuelta de 360 grados, girando sin parar (por decirlo de alguna forma), verdad?
to circulo
  repeat 360[forward 1 right 1]
end



Y ahora... espirales :)
Para esto vamos a utilizar funciones recursivas, para quien no sepa lo que son, las funciones recursivas son las que se llaman a si mismas, por ejemplo el factorial:
si x es 0-> factorial(x)=1
sino-> factorial(x)=x*factorial(x-1)

Por supuesto, hay mas formas de hacerlo, pero esta forma de trabajar nos permitira hacer fractales mas adelante *-*

A lo que hiba, para dibujar una espiral se necesitan varios datos, en este caso vamos a usar la distancia del paso, el angulo de giro y un limite de tamaño, el pseudocodigo seria este:

para espiral :distancia :angulo :limite
   si :distancia>:limite [para]
   avanza :distancia
   gira :angulo
   espiral :distancia+1 :angulo :limite



Veamos detalladamente lo que hace:
 
si :distancia>:limite [para]
Si ya pasamos el limite, ya acabamos
...
Sino
avanza :distancia
girar :angulo

Estos dos no necesitan explicacion, no?
espiral :distancia+1 :angulo :limite
Y hacemos que la espiral siga avanzando, pero ahora, que la distancia sea mayor (para que se vaya "abriendo")

Si pasamos el codigo a Logo...
to espiral :distancia :angulo :limite
  if :distancia>:limite [stop]
  forward :distancia
  right :angulo
  espiral :distancia+1 :angulo :limite
end

Asi, haciendo espiral 0 90 200 (un angulo de 90 para que sea cuadrado) conseguimos:
Pero si cambiamos el angulo un poco... espiral 0 91 200



Ademas, le podemos añadir alguna variable mas para controlarlo mejor

to espiral :distancia :angulo :limite :incremento_distancia
  if :distancia>:limite [stop]
  forward :distancia
  right :angulo
  espiral :distancia+:incremento_distancia :angulo :limite :incremento_distancia
end


Esto añade la opcion de separar mas las lineas, por ejemplo, si a la primera figura se le pone 2 de separacion (1 es el que se usaba antes)... espiral 0 90 200 2
o con el angulo cambiado... espiral 0 91 200 2


Ahora a lo divertido... :D

Con esta funcion, y jugando con filtros de imagenes se  pueden conseguir cosas bastante curiosas... por ejemplo:
Usando espiral 0 121 200 1 obtenemos esta imagen:
 
 Y usando un filtro "Olify" de la categoria "Artistic" (o "Pintura al oleo" de "Artistico") del GIMP:
 
Supongo que en estos casos (cuando se pierde informacion al aplicar el filtro) es mejor ampliar la imagen antes de usar el filtro, asi se notara menos ;)

Y si despues añadimos algo de color...



Ya esta :D!

PS: Tenia pensado hacer un script que cambiase el color de una imagen segun cuanta "luz" hay alrededor ( cuantas mas lineas blancas , mas "luz" ), para hacer efectos directamente con las imagenes de Logo, sin necesidad de un programa de manipulacion de imagen, pero se de imagenes lo que un gato de fisica cuantica, asi que no prometo nada :P

Hasta otra!

[Interpretes]
UCBLogo  ( http://www.eecs.berkeley.edu/~bh/logo.html ) (multiplataforma) [GPLv2]
XLogo ( http://xlogo.tuxfamily.org/sp ) (en Java) [GPL]

FMSLogo ( http://www.fmslogo.org ) ( para Windows ) [GPL]

[Referencias]
Wikipedia
http://neoparaiso.com/logo/
http://et.bgcbellevue.org/logo/

domingo, 7 de marzo de 2010

SSH: Conexiones seguras para tod@s ( II ) SSHFS

Siguiendo con la segunda parte de SSH: Conexiones seguras para tod@s, ahora SSHFS... la idea era mostrar tambien las VPN's, pero ahora mismo no es posible  :(, prometo que pronto saldran ;)

SSHFS

¿ Que es SSHFS ?
Es un cliente que permite montar un sistema de archivos remoto en una carpeta local ("bajo la superficie", el cliente funciona con SFTP, con lo que las comunicaciones van cifradas adecuadamente)

Instalandolo
La instalacion es la tipica, no me voy a liar con esto, lo unico decir que usa FUSE, si no viene instalado por defecto (que me extraña), cualquier gestor de paquetes decente deberia instalarlo con sshfs, el resto es el clasico sudo apt-get install sshfs (para basados en debian, por ejemplo)

Montando una carpeta
El comando para montar una carpeta es
sshfs [<usuario>@]<host>:[<directorio>]  [-p <puerto>] <punto de montaje>
Los parametros son:
Usuario: si el usuario es distinto en el host que el que se esta utilizando actualmente
Host: direccion a la que se conecta
Directorio: raiz de sistema de archivos (si es distinta al directorio HOME del usuario)
Puerto: si se usa un puerto SSH no estandar (distinto del 22)
Punto de montaje: carpeta local a traves de donde se accede al SSHFS

Como se puede ver, el comando es bastante parecido al de ssh, de hecho, si no se tiene la clave publica del host (o si ha cambiado), hace lo que haria ssh ( y pedira la clave  del usuario )

Una  vez montada, se puede navegar por la carpeta como si fuera una normal

Desmontando una carpeta
El comando para desmontar una carpeta es
fusermount -u  <punto de montaje>

El unico parametro, Punto de montaje, sirve para especificar la carpeta donde se monto el SSHFS

Y ya esta!

[Referencias]
http://tuxpepino.wordpress.com/

Hasta ahora!!