miércoles, 20 de agosto de 2014

Cifrado XOR y One-time pad


El método de cifrado XOR es un método que, como su nombre lo indica, utiliza el operador lógico XOR. El operador XOR devuelve 1 (o verdadero) siempre y cuando sólo uno de sus entradas es igual a 1, en caso contrario devuelve 0 (o falso).

La tabla de verdad del operador XOR para dos entradas quedaría así:


En el caso que se utilice este operador para dos cadenas binarias, se aplica el operador XOR para cada bit de las dos cadenas, resultando en una nueva cadena binaria, como se muestra en la siguiente imagen.


Este operador es muy útil en Criptografía, pues imaginemos que la cadena binaria A es el mensaje, la cadena binaria B es la llave y C = A XOR B es el mensaje criptado. Si se desea recuperar el mensaje original, sólo es necesario aplicar el operador XOR para la cadena C y la cadena B, por lo que resulta que A = C XOR B.

Si bien este método es muy sencillo de implementar también es cierto que es fácil de atacarlo, en especial si la llave siempre es la misma. Para evitar este problema el concepto de One-time pad (libreta de un sólo uso) viene muy bien al caso, ya que son como una especie colección de llaves aleatorias que dos usuarios comparten.

Imaginemos que tenemos dos usuarios, Alice y Bob y que se ha generado un one-time pad de 10 llaves y los dos tienen una copia de este one-time pad. Cada vez que un usuario envía un mensaje al otro, se encripta el mensaje utilizando una llave de su propio one-time pad, para proceder a eliminar dicha llave de su libreta. Luego, el receptor recibe el mensaje criptado y lo recupera utilizando la llave de su propia copia del one-time pad, procediendose a eliminarse dicha llave de la libreta del receptor. Nótese que la llave en ambos operaciones  siempre es la misma, aunque está almacenada en dos lugares distintos. En este ejemplo el proceso de comunicación se podría repetir hasta 10 veces, que es el número de llaves disponibles para los dos usuarios, y en teoría, si se utiliza llaves verdaderamente aleatorias es prácticamente imposible romper la seguridad de un sistema que implemente one-time pad.

Se implementó en Python una especie de sistema one-time pad, que consiste en dos programas principales: un generador de llaves pseudoaleatorias y un programa que encripte y desencripte mensajes. Antes de continuar, es necesario mencionar que nuestras llaves y nuestros mensajes pueden contener símbolos alfanuméricos, por lo que es necesario consentir un "protocolo" para trabajar únicamente con números, en mi caso decidí trabajar con números Unicode, es decir, el número entero que representa un caracter en Unicode. Entonces ya que queda claro que todos los caracteres de mis llaves y mensajes se pueden representar como números, procedo a mostrar un pequeño ejemplo de esto.






Para generar llaves pseudoaleatorias es necesario mandar como argumentos el número de llaves a generar así como el tamaño de las mismas.. Para empezar con "la comunicación" es necesario que existan los archivos de llaves para los dos usuarios y también un archivo de texto que contenga texto cualquiera, el cual va a ser nuestro mensaje original. En el programa de encriptación, por tanto, se manda como argumentos los nombres del archivo que va a servir como el mensaje y también los nombres de los archivos que contienen las llaves. Ya que esto es una simulación de como se podría implementar one-time pad, la desencriptación del mensaje lo realiza en automático, mostrando en pantalla el contenido del mensaje original.

Los resultados se muestran a continuación.




Referencias:

domingo, 10 de agosto de 2014

ROT13

ROT13 es un método de cifrado simple, en el que las letras de un mensaje son remplazadas por la letra que se encuentra trece posiciones después de la misma en el abecedario.

Ya que este método trabaja con el abecedario, para convertir una letra en su equivalente en ROT13 es necesario conocer su posición y sumar trece, así se encuentra la posición de la letra que se utilizará para encriptar la original. Así, la letra A (1) se convierte en N  (14), la letra B (2) se convierte en O (15), la letra M (13) se convierte en Z (26), etcétera.

El método se puede ver de dos maneras: si son las primeras trece letras, se suman sus posiciones, y si son las últimas trece, se restan. Pero también es posible auxiliarse del módulo, por ejemplo, la letra U está en la posición 21 del abecedario, su suma sería 34, que claramente no existe. Para "dar la vuelta" al abecedario es necesario conocer el residuo entre la suma y el número total de letras. Así pues, ya que 21 cabe una vez en 34, "sobra" 8, es decir, la letra cifrada sería H. De esa manera es posible realizar la operación de una manera práctica y directa. Dado a que estamos sumando la mitad del número de letras en el abecedario, eso quiere decir que se puede implementar una sóla función en ROT13 que trabaje para cifrar y decifrar el contenido de los mensajes.


Además de que es un método muy conocido, y por eso mismo poco fiable, existe una razón por la que es fácil romper la seguridad de un mensaje cifrado en ROT13, y es conocer la frecuencia en la que aparecen las letras del abecedario en el texto. Es decir, si sabemos que la letra E (5) aparece con más frecuencia en el idioma inglés, ¿no es fácil deducir que la letra R (18) se encontrará más veces en un texto cifrado con ROT13?

A pesar de que hay muchas fuentes que está de acuerdo en la distribución de las frecuencias de las letras del abecedario, decidí realizar un experimento con un texto de la Wikipedia para probar esta teoría. Los resultados se muestran a continuación.

Análisis de frecuencia

El programa anterior realiza un conteo de las letras del abecedario en Inglés -que previamente se define en una lista- que aparecen con mayor frecuencia en un texto. El texto se encuentra almacenado en un archivo de texto, al cual es accedido cuando el usuario manda el nombre del archivo como parámetro. Al final el programa guarda en otro archivo los resultados del análisis de frecuencia, en donde cada fila hace referencia a la letra y su correspondiente porcentaje de frecuencia.

El formato en el que se guarda la información no es simple casualidad, ya que si está almacenado de esta manera es más fácil realizar una gráfica de dicha información con el siguiente comando de Gnuplot.



En base a esta gráfica, las letras que más aparecen son la e, a, t, n y o. En cambio, las que menos aparecen son las q, j, x, z, v. Conociendo esa información, eso quiere decir que las letras r, n, g, l y b van a aparecer mucho más que las letras d, w, k, m y i en un texto cifrado con ROT13. El mismo programa fue utilizado en un texto distinto que fue cifrado en ROT13 para comprobar la hipótesis.


Más o menos se puede observar una semejanza, ¿verdad? Si se sospecha tan siquiera que una letra aparece con más frecuencia que otras, este ataque puede acabar rápido con un mensaje cifrado en ROT13.

Además de este pequeño análisis también implementé ROT13 con Python, pudiendo analizar cadenas pequeñas o inclusive textos enteros para luego cifrarlos.