miércoles, 10 de julio de 2013

Cifrado de Flujo HC-256

El algoritmo de cifrado de flujo HC-256 se utiliza (al igual que los demás algoritmos de cifrado de flujo) para cifrar claves compartidas. Los cifrados de flujo se ejecutan 4 a 5 veces más rápido que un cifrado por bloques, sin embargo se han publicado pocos cifrados de flujo eficiente y seguro. 



Algoritmo HC-256 

El proceso es relativamente fácil, para cifrar se aplica la operación XOR entre el keystream y el mensaje a cifrar, el descifrado es aplicar la operación XOR entre el keystream y el texto cifrado. Para poder realizar esto hay que entender cómo generar las claves, y para todo esto es necesario el proceso descrito en los siguientes párrafos.

Para la generación del keystream es necesario:
  • Establecer una clave (K) y un vector de inicialización (IV) ambos de 256 bits
  • Se deben tener dos tablas (Tabla P y Tabla Q), cada una contiene 1024 elementos de 32 bits, cada elemento $i$ de P o Q debe ser mayor o igual que 0 pero menor que 1024.
  • El keystream (s) es generado por el algoritmo, a partir de la concatenación de las salidas ($S_{i}$), es decir $S=S_{1} || S_{2} || \dots$
Hay seis funciones utilizadas para este proceso en el algoritmo de cifrado HC-256, y hay que tomar en cuenta que para las funciones $g_{1}(x)$ y $h_{1}(x)$ se utiliza la tabla Q como caja de sustitución (S-box) y para las funciones $g_{2}(x)$ y $h_{2}(x)$ se utiliza la tabla P como caja de sustitución(S-box).


$$f_{1}(x) = (x >>> 7)\oplus(x >>> 18)\oplus(x >> 3) $$
$$f_{2}(x) = (x >>> 17)\oplus(x >>> 19)\oplus(x >> 10) $$
$$g_{1}(x, y) = (x >>> 10)\oplus(y >>> 23) + \mathrm{Q}[(x\oplus y)\mod 1024]$$
$$g_{2}(x, y) = (x >>> 10)\oplus(y >>> 23) + \mathrm{P}[(x\oplus y)\mod 1024]$$
$$h_{1}(x) = \mathrm{Q}[x_{0}] + \mathrm{Q}[256 + x_{1}] + \mathrm{Q}[512 + x_{2}] + \mathrm{Q}[768 + x_{3}]$$
$$h_{2}(x) = \mathrm{P}[x_{0}] + \mathrm{P}[256 + x_{1}] + \mathrm{P}[512 + x_{2}] + \mathrm{P}[768 + x_{3}]$$

Donde $x$ es la concatenación de caracteres de forma que crean una palabra de 32 bits es decir $x = x_{3} || x_{2} || x_{1} || x_{0}$, donde $x_{3}$ seria los bits mas representativos y $x_{0}$ los bits menos representativos.


Inicialización de proceso (Clave y Vector de Inicialización)

 El proceso de inicialización consiste en expandir la clave (K) y el vector de inicialización (IV) en las tablas P y Q, y realizar 4096 iteraciones sin generar la salida ($S_{i}$).


  • La clave (K) y el vector de inicialización (IV) se expanden en una matriz $W_{i}$ (debe ser mayor o igual a 0 y menor a 2560) de la siguiente manera:




  • Se actualiza las tablas P y Q con los valores de la matriz W.

  • Se ejecuta 4096 iteraciones del cifrado sin los valores de salida.
El proceso de inicialización se completa y esta listo para generar el keystream.

Generacion de claves (keystream)


Por cada iteracion es actualizado un elemento de una tabla y es generada una salida de 32 bits. Una caja de sustitucion (S-box) es utilizada solo para generar 1024 salidas, después de esto se actualiza la caja de sustitución (S-box) para las siguientes 1024 salidas. El proceso de generación del keystream del HC-256 es la siguiente:


Nota: El simbolo $\fbox{-}$ denota  "-"$\mod1024$.

Una vez se tenga el keystream se procede a encriptar o desencriptar como se describe al inicio.


Bibliografia

martes, 9 de julio de 2013

Cifrados por Bloque - Blowfish

Blowfish es un algoritmo de cifrado por bloques simétrico libre de patente creado por Bruce Schneier en 1993 como una alternativa para reemplazar a DES como estándar de cifrado. Este algoritmo esta compuesto por 18 semiclaves (K) y 4 cajas (subtitution boxes S). Es un proceso relativamente simple y altamente seguro ya que a la fecha no se conoce ningún tipo de criptoanalisis efectivo contra este algoritmo de cifrado.

Algoritmo de cifrado



Para poder entender el algoritmo primero tendremos que describir la funcion F, la cual se encarga de sustituir los valores resultantes de las operaciones XOR utilizando las cajas de sustitución(subtitution boxes).

La función F divide el grupo de 32bits en 4 grupos de 8bits el bloque a y bloque b se buscan en las cajas sustitución(representadas con la letra "S" en el diagrama), el valor representado por el primer octeto de la primer caja se suma al valor representado de el segundo octeto de la segunda caja y al resultado se saca el modulo de 2³², posteriormente a este resultado se aplica una operación XOR con el valor representado por el tercer bloque en la tercer caja y al resultado de esto se le suma el valor representado por el cuarto octeto en la cuarta caja y al final se vuelve a aplicar el modulo 2³².



Scheier describe la funcion F como:
$$f(L_{i} \oplus K_{i})= ((((S_{1}[A] + S_{2}[B])\mod{2^{32}})\oplus S_{3}[C]) + S_{4}[D]) \mod{2^{32}}$$

Una vez entendido que es la función F del Blowfish paso a describir el algoritmo de cifrado:
  • Un bloque de 64bits se divide en dos bloques de 32bits (L y R)
  • Se realiza una operación XOR a los primeros 32bits(L)  con la primera subclave(K) y se realiza la función F con el resultado de la operación.
  • Se realiza una operación XOR con la segunda parte de los 32 bits(R)  con el resultado de la función F(L).
  • Se intercambian posiciones (R pasa a ser L y L pasa a ser R) y se repite el proceso anterior por 16 iteraciones.
  • Al terminar la ultima iteracion no se realizara el intercambio.
  • Se realiza la operacion XOR entre el valor alojado en L y la subclave 18.
  • Se realiza la operacion XOR entre el valor alojado en R y la subclave 17.
  • Se unen los dos fragmentos del bloque para generar nuevamente un bloque de 64bits ya cifrado.
Las subclaves y las cajas de substitución no corresponden a valores arbitrarios, estos valores son el resultado de un proceso previo a la encriptacion o desencriptacion con Blowfish.

Planificación de claves

La planificación es la inicialización del arreglo de las subclaves haciéndolas dependiente de la clave de usuario. Estos valores serán las subclaves para el proceso de encriptacion y desencriptacion con Blowfish por lo tanto deben calcularse antes de comenzar a cifrar o descifrar mensajes propios.

Proceso:

  • Se define un arreglo de 18 secciones las cuales deben de poder almacenar 32bits cada una ya que estas alojaran las subclaves, ademas se generan 4 arreglos de 256 posiciones tambien de 32bits cada una, estas ultimas son las cajas de substitución.
  • Cada sección de los arreglos (subclaves y cajas) son inicializados con una cadena fija, esta cadena son los digitos en hexadecimal de $\pi$ a excepción de su parte entera. El orden de inicialización es $P_{1}, P_{2}, P_{3}, \dots, P_{18}, S_{1}, S_{2}, S_{3}, S_{4}$
  • A cada una de las subclaves se le aplica un XOR con 32bits de la clave de usuario. 
  • Una vez inicializadas las cajas y las subclaves, se cifra un mensaje nulo (lleno de ceros)
  • El paso anterior tiene 2 funciones, primero sustituye las primeras dos subclaves y segundo entra a Blowfish para ser cifrada(con las subclaves sustituidas).
  • Se repite el paso anterior pero esta vez se sustituyen las siguientes dos subclaves. Este paso se repite hasta que las 18 subclaves y el contenido de las 4 cajas hayan sido sustituidas por las salidas corresondientes del cifrado de la palabra nula.
En total se realizaran 521 iteraciones para obtener los valores que se utilizaran en el cifrado de información.

Librerías para cifrado Blowfish



Ejemplo de cifrado Blowfish con PyCrypto






Salida por consola





Bibliografia




lunes, 8 de julio de 2013

Esteganografia

La esteganografía es la parte de la criptografía que estudia y aplica técnicas que permiten el ocultar mensajes o archivos dentro de otros, los cuales son denominados portadores. Con estas técnicas se trata de ocultar mensajes dentro de otros y de esta manera establecer una forma de comunicación encubierta, de manera que el mismo acto de mantener una comunicación pase desapercibido.

Por mi parte para mostrar esta forma de ocultar información, realice dos scripts de python, el primero oculta un mensaje de texto plano en una imagen utilizando los tres canales del RGB, el segundo oculta igualmente un mensaje de texto plano en un archivo de audio de extensión WAV, ya que al no tener ningún tipo de compresión es mas fácil mantener los mensajes intactos.

Código para ocultar mensaje en archivo de audio


Ejecucion




Links de archivos de audio

Login100
Login001
Logout100
Logout001

  

Enlaces de interes

Futuras mejoras

  • Agregar mas soporte a otro tipo de archivos
  • Ocultar archivos algo mas que solo texto

jueves, 4 de julio de 2013

Repositorio de Claves Publicas RSA

..::Avance::..
Al momento solo puede validar el reto, falta enlazar u numero aleatorio desde el servidor, lo cual pienso hacerlo a través de una petición ajax y desencriptarlo con los métodos escritos en javascript.

Código proceso

Codigo Funciones Matematicas
Codigo Formulario

Las llaves publicas y la privada se almacenara en una cookie de la web para mantenerlo en un archivo y no introducirse manualmente.

Codigo Almacenamiento en cookie


martes, 2 de julio de 2013

Implementacion de Autentifiacion RSA

RSA es un sistema de criptografia de clave publica o de cifrado asimetrico, es el primer algoritmo de este tipo y ademas el mas utilizado, este sistema criptografico es usado para cifrar y para autentificar (firma digital) sesiones por ejemplo.

La seguridad de este algoritmo radica en la dificultad de la factorizacion de números enteros. Los mensajes enviados se representan mediante números y el funcionamiento se basa en el producto, conocido, de dos números primos grandes elegidos al azar y mantenidos en secreto. Actualmente estos primos son del orden de 10²⁰⁰, y se prevé que su tamaño crezca con el aumento de la capacidad de calculo de los ordenadores.

Cada usuario posee dos claves de cifrado: una publica y otra privada. Cuando se quiere enviar mensaje, el emisor busca la clave publica del receptor, cifra su mensaje con esa clave, y una vez que el mensaje cifrado llega al receptor, este se ocupa de descifrarlo usando su clave privada.

Aquí realice un código que me genera las claves publicas y privadas (ademas de cifrar con ellas algún mensaje) y un segundo código donde implentara el RSA a través de red, utilizando sockets, la implementación en red no es mas que para realizar la prueba especifica de pasar un mensaje x y este sea modificado por el cliente y el servidor lo descifre y compruebe que el resultado es exactamente el mismo, ademas de que el servidor comprueba que el usuario sea quien tiene la llave privada correcta, esto enviando un numero entero aleatorio en texto plano al cliente, el cliente cifra con su llave privada y regresa al servidor, el servidor descifrara usando la publica si el resultado es el mismo que envió el servidor indicaría que el cliente tiene la llave privada correcta.

Implantación RSA


Posteriormente en el código mostrado bajo este párrafo se muestran dos métodos, se pueden importar en un interprete de python y ejecutarlo directamente o realizar un script parecidos a estos cliente - servidor.

Pruebas con cliente - servidor

Corrida en Terminales

Aquí muestro la corrida en dos terminales donde especifico la IP y puerto donde corre el servidor, mientras que en el lado del cliente especifico IP y puerto a donde conectara, cuando inicie el cliente el servidor deberá estar andando de lo contrario arrojara un error.

Una vez se realice la conexión verificara que el cliente sea el mismo que tengo con la llave publica, si es asi esperara el mensaje a encriptar y enviar al servidor.

Al final muestra el texto cifrado y el mensaje original en ambos script (cliente y servidor).


Códigos adicionales utilizados:

Bibliografia:


Futurmas Mejoras

  • Realizar métodos de propósito genera para el cliente y servidor, esta vez solo se implementaron para la prueba de la autentifican por medio de RSA.
  • Mejorar la búsqueda y comprobación de números primos, para poder generar claves de encriptado mas grandes, ya que entre mas grandes serán mas seguras.
  • Dividir el texto cifrado para poder enviar mensajes de mayor tamaño.
  • Error la autentificacion no es completa, ya que solo se realiza de parte del cliente y debe ser de ambos lados, completar la rutina.

lunes, 1 de julio de 2013

Protocolo Diffie-Hellman

Este protocolo permite el intercambio de claves entre dos partes las cuales no han tenido contacto y este intercambio se lleva de manera secreta y anónima, utilizando un canal inseguro.


A y B intentan establecer una clave secreta y un adversario E de tal forma que:

  • Se establece un valor primo p y un generador Z, de manera que Z y p son conocidos por A, B y E.
  • A escoge un generador(Z) al azar y calcula X = generador^x mod primo y envia el resultado (X) a B.
  • B escoge un generador(Z) al azar y calcula Y = generador^y mod primo y envia el resultado (Y) a A.
  • Con esto A como B podran calcular el valor de la clave compartida 
    • Ka = Y^x mod primo 
    • Kb = X^y mod primo

Para realizar el análisis, esta vez se calcularon diferentes números, pequeños para realizar un análisis simple y posteriormente con números mayores en un análisis computacional, en los ejercicios escritos no se presento ninguna novedad ya que los números eran de un grupo pequeño para no realizar demasiadas operaciones repetitivas. En las corridas computacionales ya que se realizaron pruebas con números mayores, el intentar obtener los valores de "x" e "y" de Alice y Bob (respectivamente) en algunas corridas de valores altos retornaba algún valor del cual en el cual es divisible "x" o "y" según sea el caso.

Código pruebas Diffie-Hellman:

Corridas Computacionales:


Conclusiones:

En conclusión, para dificultar un ataque por fuerza bruta es conveniente el mantener en un valor alto el modulo elegido para la generación de la llave, esto hará que nuestro generador Zp sea de un rango mayor, por lo cual un ataque por fuerza bruta sera complicado y desesperante por el tiempo de las iteraciones que tendrá que realizar para la búsqueda de los valores originales de "x" e "y" y la solución de la clave compartida.

Bibliografia:

Análisis de Números Pseudoaletorios 

Para la generación de números pseudoaleatorios existen varias métodos adema de poder implementar los propios, pero para poder tener una generación considerablemente aleatoria de números se realizan diversas pruebas, entre ellas pruebas de correlación, pruebas de frecuencia.

La mayoría de los generadores utilizados en software comerciales pasan por lo menos dos pruebas para mantener la confiabilidad de la pseudoaleatoridad, por lo decidí aplicar las dos pruebas anteriormente mencionada a los generadores de números pseudoaleatorios nativos de diversos lenguajes de programación (c, java, python y ruby), con ello verificar que pasen las pruebas de generación de números pseudoaleatorios para su frecuencia y correlación.

Los métodos aplicados son:

  • Kolmogorov-Smirnov
  • Prueba de Series
Código de Prueba de Series
Código de Prueba Kolmogorov-Smirnov
Código de pruebas implementadas


Las pruebas se corrieron tres veces así como su generación de números pseudoaleatorios, a continuación muestro los resultados de las corridas al cual le paso como parametro el archivo generado por cierto lenguaje y un valor n para la prueba de series, cada archivo contiene 20000 números pseudoaleatiros entre 0 y 1 excluyendo este ultimo.

Nota: valor de tablas para la prueba de series ejecutada es de 7.81

En conclusión al ver que los generadores de ruby y python mantienen los resultados de las pruebas en valores bajos, mientras que java pasa de valores bajos a valores altos (en prueba de series) , a diferencia de la prueba de frecuencia (Kolmogorov-Smirnov) que se mantiene con poca variación, mientras que c al no modificar la semilla inicial no realiza ningún cambio, se utilizo el 1 como semilla, ademas en c es el único que se encontró números repetidos.

Podríamos decir que los generadores de ruby y python son los que dieron mejores resultados, en cuanto a las pruebas de frecuencia y correlaciones, por lo cual se puede decir que genera valores distribuidos y con buen grado de aleatoriedad ya que los valores de pruebas de series se mantienen bajos, así como la prueba Kolmogorov-Smirnov.

Mejoras Futuras:


  • Otorgar el valor de Tablas para la comparación final de aprobación de los números pseudoaleatorios.
  • Realizar pruebas con algunos otros lenguajes y probar mas corridas.
  • Crear método para correr automáticamente n cantidad de corridas ademas de especificar todos los archivos y no probar uno a uno.

Bibliografia

Presentación de números aleatorios, generación y pruebas

Métodos para probar números aleatorios

Gráficas con Python y Gnuplot

miércoles, 26 de junio de 2013

One Time Pad 

 One Time Pad es un algoritmo de cifrado que se basa en llaves aleatorias y nunca reutilizadas, la intención de no reutilizar las llaves mas de una ves es para incrementar la dificultad cripto analítica.

El uso a grandes rasgos es de la siguiente manera, se mantienen dos archivos de llaves, cada vez que se encripte o desencripte algún mensaje se eliminara las llaves utilizadas, por lo cual el uso de estos archivos debe ser exclusivo entre una comunicación entre los poseedores de los archivos de llaves.

A continuacion muesto el metodo de encriptacion y desencriptacion.

Si deseas ver el código completo clic aqui

Ejemplo de ejecución:


Referencias: 


Python Number abs() Method

Problemas:

  • Si el archivo de llaves no existe cuando se quiere encriptar o desencriptar, marcara error y finalizara el programa, en el método para leer archivo tendría que poner un try - except para mandar a la generación o avisar que no existe el archivo.
  • Si se agregar caracteres diferentes a el abecedarios y los números provocara un error al no encontrarlo, la solucion mas fácil es expandir las opciones del diccionario para que incluya los caracteres. (Ejemplo: Jose? o José, cometen error por el acento y por el signo de interrogacion que no estan incluidos).
  • Si las llaves no son suficientes para encriptar el texto marcara error, debo validar que el texto no supere la cantidad de llaves existentes en el archivo y avisarle al usuario en caso contrario.