Cifrador de texto con Arduino

Llevo poco tiempo con Arduino, así que mis realizaciones son modestas, he montado los típicos circuitos de leds, control de servos con infrarrojos y desde el PC a través de la conexión serie y ahora estoy desarrollando un variador trifásico para controlar una bomba de vacío del tipo turbomolecular, que gira nada más ni nada menos que a 60.000 rpm. Pero hace una semana se me ocurrió hacer algo distinto, un programa de cifrado de texto que residiera en el Arduino, es decir, que mediante conexión serie se le envíe una contraseña y un texto en claro, y la placa lo devuelva al ordenador ya cifrado, de la misma manera que si se le envía cifrado, lo devuelva en claro.

Ya sé que existen incluso implementaciones del sofisticado sistema AES (Advanced Encryption Standard) adaptado a procesadores de 8 bits, pero en mi caso no es que lo necesite para algo concreto, y el desarrollar un sistema semejante es por el reto de hacerlo, por puro placer, y además descartando complejidades como la factorización de grandes números primos o el cifrado de curva elíptica. En vez de eso pienso utilizar algo que ya usaba Julio César en la Guerra de las Galias, aunque naturalmente con algunos "sutiles cambios".

Seguramente muchos habréis oído hablar del método de este insigne emperador romano, que en los mensajes simplemente sustituía cada letra por la que ocupaba el puesto +2, +3 o +4 en el alfabeto. Así que el nombre de la ciudad de "lutecia" (la actual París), cifrada en clave +2 sería "nwvgekc", donde la primera "n" viene de "l"+2, la "w" de "u"+2 etc...

Por suerte para César, los galos de Vercingétorix no disponían de lingüistas demasiado expertos, porque en caso contrario, este simple cifrado de sustitución monoalfabética, muy fácil de romper mediante un simple análisis de la frecuencia con que aparecen las letras en un idioma determinado, habría revelado sus planes y tal vez la batalla de Alesia habría acabado de manera muy distinta...

En fin, ese sistema lo sofisticaron de forma considerable los alemanes en los años 30 con sus máquinas Enigma. Ya que si bien también se sustituía un alfabeto por otro, en realidad lo hacían con un alfabeto distinto para cada carácter, con lo cual el análisis de frecuencias no servía de nada y tanto los polacos primero como los ingleses después tuvieron que poner a trabajar sus mejores mentes para romper el cifrado...

La Enigma utilizaba tres o cuatro rotores con contactos eléctricos, que iban rotando en una cierta secuencia a cada pulsación de una tecla, de manera que creaba una cantidad ingente de "sustituciones" entre el carácter que se pulsaba y la letra que finalmente se encendía en el panel. Dicho cifrado sólo podía revertirse colocando los ajustes de la máquina, es decir, su clave, en la misma posición inicial, y tecleando de nuevo el mensaje cifrado, que sólo se esta manera aparecía en claro en el panel...

Algunos modelos de Enigma tenían hasta 159 trillones de posibilidades de clave, la cual además se cambiaba cada día, y por tanto no servía de nada disponer de un pequeño ejército de operadores con copias de la máquina para ir probando. la Enigma sólo pudo ser vencida descubriendo ciertos errores que cometían los alemanes en el protocolo de cifrado de sus mensajes, lo cual, bien interpretado por los criptógrafos de Bletchley Park permitía descartar la mayoría de posibilidades, dejando el resto, que seguía siendo un número muy alto, a las famosas secuenciadoras electromecánicas llamadas "bombas", diseñadas por el genial Alan Turing...

Mi idea es implementar un sistema semejante pero mucho más potente, aprovechando las facilidades que nos dan los procesadores, y además hacerlo de manera que deje el mínimo rastro en el ordenador. El programa residirá en la memoria flash del Atmega328P del Arduino, se procesará en su sram y aprovechará su generador de números aleatorios para crear un altísimo número de alfabetos de sustitución. Aunque debemos precisar que tales números no son exactamente aleatorios, porque en realidad son calculados por una fórmula y pertenecen a una larga aunque previsible secuencia de 2.147.483.647 números (al menos en C) que se repite al acabar. La clave, como en las Enigmas, es el "punto" de la secuencia en que arranca, que debe ser el mismo en el cifrado y en el descifrado, porque cualquier mínima diferencia, aunque sea de un solo dígito, arrojará resultados totalmente ininteligibles.

A su vez, la entrada y salida de textos se realizará a través de la ventana serie del IDE Arduino u otro programa serie, como el conocido Hyperterminal, integrado dentro del sistema operativo XP, el Realterm de software público, o cualquier otro de los que hay a decenas gratis en la red...

Pero en fin, como el asunto es un poco largo, continuaré mañana...

Un saludo a todos

Bienvenido Anilandro.
Es grato encontrarte por aquí ya que, según creo, eres el Anilandro de cientificos aficionados.

Un saludo y cuando formules tus dudas estaremos encantados de intentar ayudarte.

En efecto, Alfaville, soy el mismo Anilandro. En cuanto a dudas, seguro que voy a tener que acudir a vosotros muchas veces, ya que llevo bastante tiempo sin trastear con microcontroladores y el C también lo tengo bastante oxidado...

Un saludo

Repito la bienvenida.
Un saludo.
PD.
Nos enseñaras tú mas a nosotros que nosotros a tí.

Conoces esta librería Arduino AESLib?

Sí que la conozco, pero como digo en el texto, en este caso no se trata de utilizar algo ya hecho para una necesidad concreta, sino programar algo distinto simplemente por puro reto, un algoritmo basado en sistemas de criptografía clásica pero aprovechando la potencia del cálculo del procesador... y de hecho ya lo tengo funcionando de manera satisfactoria...

...Mañana colgaré un poco más sobre este tema.

Un saludo

Lo aportaba solo a titulo compartivo.
Por tu descripción inicial sabes de lo que hablas entonces sería interesante hacer un benchmark u otro tipo de prueba.

Realizar algún tipo de test sería muy interesante, pero en criptografía es muy complejo, porque a veces las cosas no son lo que parecen y los grandes números no lo dicen todo. Decía que el algoritmo funciona bien, pero me estoy encontrando con un bug extraño que tiene que ver con la diferente forma de interpretar los caracteres no imprimibles por parte de distintos monitores serie... esta mañana se me ha ocurrido algo que tal vez lo solucione...

...Pero no quiero saltarme etapas. Sigo describiendo el proyecto tal como lo fui desarrollando en estos días pasados:

=============================

La idea es un sistema de cifrado "externo", que utilice el ordenador como monitor de entrada y salida pero que el proceso se realice enteramente en el Arduino. El algoritmo de cifrado lo basaré en el generador de números pseudoaleatorios del Wiring (que supongo de las mismas características que el C estándar). La contraseña será simétrica, es decir, la misma para el cifrado y el descifrado, y su acción interna consistirá en establecer el "Seed", la semilla del generador, a partir de la cual la secuencia es siempre la misma...

...Los números generados se irán sumando secuencialmente al código ASCII de los caracteres del mensaje a cifrar. El resultado será otro número que representa el carácter cifrado...

...Como es muy posible que el carácter resultante no sea imprimible (menor de 32 o mayor de 126), una rutina convertirá la salida en un "alfabeto circular". Imaginemos que utilizamos un alfabeto de 26 letras (en realidad utilizo muchas más, ya que están los números, las mayúsculas y los signos gráficos)... bueno, si fueran 26 letras, un alfabeto circular sería que tras la "z" viene de nuevo la "a", de manera que una "y" inicial a la que le "sumamos" 4, resultaría la letra "c"...

...La secuencia de caracteres "cifrados" será devuelta al PC a través de la conexión serie...

...Para descifrar, la contraseña establece el mismo "Seed", pero los números pseudoaleatorios ahora se restan secuencialmente a los valores ASCII de los caracteres de entrada. Se aplica la corrección inversa sobre el alfabeto "circular", y el resultado "descifrado" se devuelve al PC...

Vale, en teoría todo esto está bien, pero hay un problema con el generador de números pseudoaleatorios del C-Wiring, que su secuencia sólo llega a 2.147.483.647, de tal forma que probáramos todas las "semillas" posibles, sin duda podríamos decodificar el mensaje... Hacerlo a mano sería imposible, efectivamente, pero un hasta un PC utilizado en un ataque de "fuerza bruta" podría dar cuenta de esta cifra en poco tiempo, y no digamos los "monstruos" que tiene la NSA...

...Por este motivo complicaré un poco las cosas ¿con una secuencia tan relativamente corta, cómo podemos aumentar el número de posibilidades? Pues con el multicifrado, con cifrar y recifrar el texto las veces que queramos, pero siempre utilizando "semillas" pseudoaleatorias distintas. Estas semillas las extraeré de diversas partes de la contraseña, cada tres caracteres o fracción generarán una "Seed" distinta y un nuevo cifrado. Una contraseña "abc" creará un sólo cifrado, pero la contraseña "abracadabra" generará cuatro (yo lo llamo cifrado de nivel 4)...

¿Y cuantas serían las posibilidades en estos casos?

...Pues como la contraseña puede utilizar 93 signos alfanuméricos distintos, una contraseña de 3 dígitos tiene 93x93x93 = 804.357 posibilidades, pero si volvemos a cifrar con otros tres dígitos, este número se eleva al cuadrado, hasta los 646.990 millones, y con una contraseña de 9 dígitos se eleva la cubo, alcanzando los 520.411 billones, etc

1 cifrado, 804.357
2 cifrados, 646.990 millones
3 cifrados, 520.411 billones
4 cifrados, 418.596 trillones
5 cifrados, 336.700 cuatrillones
6 cifrados, 270.827 quintillones

Vemos que con solo seis cifrados (contraseña de 18 dígitos), la cifra ya es descomunal, 270.827 quintillones (2,7 x10^35)... pues bien, con una contraseña de 60 dígitos llega a la inimaginable cifra de 1,285218336e+118, un número muy superior a la cantidad de átomos que se calcula que existen en el Universo, así que en teoría, el modestito procesador Atmega328P de 8 bits, utilizando una variación del cifrado de Julio César, dejaría a máquinas como la Enigma (159 trillones de posibilidades) a nivel del virus que depreda a la bacteria que merodea en un grano de polvo sobre el betún del zapato...

¿Y cuánto se podría tardar en romper un cifrado semejante por "fuerza bruta"?

Pues imaginando un superordenador capaz de probar 1.000 billones de combinaciones por segundo (de billones europeos, de un millón de millones), un simple cálculo nos dice que para probar todas las contraseñas posibles de 60 dígitos con 95 caracteres distintos tardaría 4,05x10^91 años ...y teniendo en cuenta que la edad del universo se estima en 1,38x10^9 años, pues ya podemos imaginarnos la cantidad de "universos" que harían falta para hallar una sola contraseña.

...Naturalmente, ésta es la teoría, porque está el asunto de los futuros o presuntos ordenadores cuánticos y sus fantásticas características, y además la historia nos ha demostrado que a veces existen atajos matemáticos para solucionar problemas que parecen imposibles. Eso ya lo comprobaron en carne propia los alemanes en la IIGM, cuando estimaban que para la tecnología de la época era imposible probar los 159 trillones de contraseñas de sus Enigma. Aunque en honor de la verdad, hay que decir, que tanto los polacos primero como los ingleses después, consiguieron romper el cifrado a causa de errores del protocolo con que cifraban sus mensajes, y no por las debilidades de la máquina en sí.

Continuará...

Un saludo a todos

Hola Anilandro.

¿ Debe entenderse pues que haces la encriptacion caracter a caracter ?

Sí, la encriptación se efectúa carácter a carácter, sin mover ninguno de sitio, es decir, es una sustitución (mejor dicho, una multi-sustitución). Añadiendo permutaciones sería aún más complejo, pero no creo que valga la pena…

Saludos

Entonces razonemos:

  • Para cada pasada de encriptación, es decir para cada semilla, hacemos una operacion a nivel de caracter (byte) para todos los caracteres del mensaje (sea XOR, suma, etc).

  • Cada caracter (8 bits) admite una máximo de 256 codigos distintos (numeros).

  • Por lo tanto estoy recodificando una y otra vez cada caracter con la semilla de turno pero arrojando un texto cifrado de 1 entre 256 posibilidades.

Bastaria con operar el mensaje con numeros entre 0 y 255 buscando "legibilidad" para abrir un camino a la rotura del cifrado, y no importa cuantas vueltas le hayamos dado porque al final no hay trillones ni exponentes de tres digitos, solo 256 combinaciones.

Hay que observar que costaria lo mismo romper el cifrado de un solo caracter que el del resto del mensaje.

Ahora me darás el mazazo, lo sé, pero no alcanzo a verlo de otro modo.

Bueno... :slight_smile: si haces una exploración de esta forma buscando "legibilidad", lo único que vas a conseguir son todas las obras literarias que se han escrito hasta ahora y todas las que se pueden escribir en el futuro con estos caracteres, entre ellas mi mensaje y cualquier otro que se pueda escribir entre una infinidad insondable que no será solamente con exponentes de 91 dígitos, si no de muchísimo más...

...Esto es como la entelequia de la biblioteca universal que alguien propuso: un libro sólo con la "a", otro con la "b", etc, y cuando se acabe el alfabeto, continúan con la "aa", la "ab", y cuando se llegue a "zz" se siguen con la "aaa" y así sucesivamente... Sin duda la mayoría de los textos no tendrán sentido, pero en la inmensidad de la biblioteca, buscando en un catálogo de títulos tan largos como las propias obras, encontrarías cualquier obra literaria posible, cualquier texto, etc...

De hecho, tampoco serviría de nada efectuar permutaciones de caracteres, porque para descifrar cualquier cosa no te haría falta ni tener el texto cifrado, sólo saber su longitud... lo que sí te haría falta sería esperar hasta el final de la eternidad y luego tener la paciencia de leer uno a uno el casi infinito número de textos generados y decidir cual de ellos (aunque sólo sea entre los que tienen sentido) corresponde al mensaje en claro original...

Saludos

No me entiendes, todo tu mensaje descansa en 1 entre 256 combinaciones, repetido 4 veces. (tu nivel 4).

Pongamos el ejemplo de un solo caracter, la "A".
La voy a codificar mediante una funcion hash de cifrado y me va a dar un codigo de 8 bits (256 combinaciones), luego lo volvere a repetir 4 veces y tendré 256 combinaciones de nuevo, solo que el "enmascaramiento" del caracter "A" será mayor porque se parecerá menos a la combinacion original (41 hex), pero no parece un sistema de cifrado muy solido, creo que se podria romper con facilidad usando medios informaticos.

No es de aplicacion, creo, el ejemplo que esbozas, del mono aporreando la maquina de escribir durante unos cuantos eones,.. jejeje

Tomariamos un caracter cifrado, le aplicariamos la operacion pertinente hasta obtener un caracter "legible" y a continuacion aplicariamos el codigo al resto de caracteres, si queda descifrado, bien, si no cogemos nuestro caracter y repetimos (hablo de caracteres sueltos pero se haria sobre una cantidad significativa de ellos para encontrar la "legibilidad").

La idea de César en el mundo de la informática no parece tan buena.

Entonces ¿a qué llamas un carácter legible? ¿una "a" o un "." es legible? porque puede que en una cierta posición no tengan nada que ver con el mensaje real. No entiendo lo que planteas. No importa que el código final esté cerca o lejos del 41 inicial de la "a", lo que importa es que no se sepa la diferencia entre este 41 y el código de salida.

La fiabilidad de un sistema criptográfico es engañosa, porque la simplicidad o complejidad del proceso no tienen porqué estar relacionadas con su fortaleza. De hecho, si tu tomas una lista de números aleatorios (es decir, lo menos pseudoaletorios posible, que tengan una secuencia infinita y nulo sesgo estadístico) y los vas sumando uno a uno al código ASCII de cada carácter de un mensaje (o aplicas una función XOR, tanto da), mientras utilices esta secuencia de números una sola vez, ya le pueden meter los métodos o superordenadores que quieras, porque el mensaje es totalmente indescifrable, no hay manera humana de saber que dice ...y sólo has hecho una simple operación.

La debilidad original de mi sistema de sustitución polialfabética (no hablemos del monoalfabético de Julio César, que cité sólo como antecedente) es precisamente la baja "calidad" del generador pseudoaleatorio del C, y por este motivo aplico el multicifrado, porque las posibles "marcas" estadísticas que pueden crear la combinación de la frecuencia de las letras en un idioma determinado con la frecuencia de aparición de ciertos números en el generador, siendo muy pequeña, de diluye exponencialmente en cada nuevo cifrado. En otras palabras, daría el mismo resultado si multicifrara solamente las secuencias aleatorias entre ellas y aplicara una sola suma con el mensaje en claro al final.

Saludos

¿ Estas de acuerdo en que cada caracter se codifica con un numero entre 0 y 255 ?
¿ Estas de acuerdo en que todo el mensaje se codifica, en cada pasada, con el mismo codigo que el primer caracter ?

Y de momento paro aqui porque quizas yo te haya entendido mal.

Anilandro:
… mientras utilices esta secuencia de números una sola vez, ya le pueden meter los métodos o superordenadores que quieras, porque el mensaje es totalmente indescifrable, no hay manera humana de saber que dice …y sólo has hecho una simple operación.

No hemos hablado aqui del metodo de encriptacion :

One-time pad es un tipo de algoritmo de cifrado por el que el texto en claro se combina con una clave
aleatoria o «libreta» de la misma longitud y que sólo se utiliza una vez. Fue inventado en 1917. Si la clave
es verdaderamente aleatoria, nunca se reutiliza y, por supuesto, se mantiene en secreto, se puede
demostrar que el método de la libreta de un solo uso es irrompible.

y me parece que no es ese el que propones.

Lo primero sí. Lo segundo no, en cada pasada, cada carácter del mensaje se codifica con un código distinto...

Saludos

Entonces todo lo dicho carece de sentido.

Creí entender que era alrevés.

Seguimos,...

Ejemplo: contraseña “abrigoP&3” de 9 caracteres y por lo tanto 3 pasadas de cifrado

1 ) Con los valores de “abr” 97, 98 y114, se crea la primera semilla (seed) (114 + (98x100) + 97x10000)= 979.914
3 ) Esta semilla crea un punto de arranque de la secuencia pseudoaleatoria
4 ) Cada carácter del mensaje se suma a un número distinto salido de cada random sucesivo
5 ) Se regularizan los valores <32 o >126 con el sistema de alfabeto circular.

6 ) Con los valores de “igo” 105, 103 y 111, se crea la segunda semilla (111+(103x100)+105x10000)= 1.060.411
7 ) Esta semilla crea otro punto de arranque distinto de la secuencia pseudoaleatoria
8 ) Cada carácter del mensaje ya cifrado una vez, se suma a un número distinto salido de cada random sucesivo
9 ) Se regularizan los valores <32 o >126 con el sistema de alfabeto circular.

10 ) Con los valores de “P&3” 80, 38 y 51, se crea la tercera semilla (51+(38x100)+80x10000)= 803.851
11 ) Esta semilla crea otro punto de arranque distinto de la secuencia pseudoaleatoria
12 ) Cada carácter del mensaje ya cifrado dos veces, se suma a un número distinto salido de cada random sucesivo
13 ) Se regularizan los valores <32 o >126 con el sistema de alfabeto circular.

El resultado de estas tres operaciones de cifrado se devuelve al PC…

El descifrado sigue el mismo procedimiento de las tres pasadas pero comenzando por la última semilla y restando los valores pseudoaletorios en vez de sumarlos.

Saludos

El procedimiento: caracteres → semilla, lo habia entendido, pero por alguna razón pensé que generabas un único numero aleatorio para cada pasada.

Esa era la razón de mi porfía porque el sistema no me parecía nada seguro, claro.
Pero una vez aclarado el tema quedo a la espera de los progresos que quieras compartir.

Saludos

Decía en la exposición del proyecto que el programa básico de cifrado basado en las premisas anteriores ya lo tengo funcionando en el Arduino, y en un mensaje posterior incluiré su listado y una rápida descripción, así como los bugs que me aparecieron y la manera de solucionarlos, pero como la idea es que en el PC solo se utilice algún programa estándar de comunicación serie para enviar los textos al Arduino conectado al USB, y recibir seguidamente el texto cifrado/descifrado por el Atmega-328P, el problema con que me encuentro es precisamente que en los programas de monitorización serie de Windows, si bien las ventanas de recepción de datos suelen ser de tamaño normal y con barras laterales de desplazamiento de texto, la ventana de "envío" se reduce en el mejor de los casos a una sola línea pensada unicamente para contener unos pocos comandos, lo cual dificulta escribir un mensaje de 1.000 dígitos en este pequeño rectángulo en que solo pueden verse a la vez unos pocos caracteres...

...Naturalmente el mensaje se puede escribir antes en block de notas y copiarlo y pegarlo luego en la pequeña ventanita, pero una vez allí sigue siendo difícil de repasar y editar el contenido, aparte que algunos programas no aceptan ni de lejos una cadena tan larga de caracteres. Las pruebas las he llevado a cabo con el "monitor" del IDE Arduino, con el completo programa de comunicaciones serie Realterm y hasta con el viejo Hyperterminal de Windows de la época de los módems telefónicos, que de hecho ni siquiera tiene ventana de envío, pero sí un comando para enviar lo que esté almacenado en el portapapeles. Rebuscando un poco por la red he encontrado cuatro o cinco programas más, pero todos siguen la misma tónica de la ventana pequeña de envío, aparte que los hay que pretenden ser tan versátiles y tienen tantas configuraciones y pestañas, que su uso no sería ni rápido ni fácil para alguien sin conocimientos informáticos...

El Realterm, uno de los monitores serie más completos que he probado, que muestra en la pantalla de recepción un corto texto cifrado, aunque el formato del programa no se adapta demasiado a mis necesidades

...Los programas de apariencia más antigua son más sencillos en este aspecto, pero descubro que algunos ni siquiera pueden explorar los COM activos que haya en el ordenador, y llevan una lista fija con un par de COMs de números bajos, que muchas veces no coinciden con los virtuales que crean las placas Arduino al conectarse (ya sé que este número se puede cambiar, pero otra vez hay que entrar en la configuración de los dispositivos del PC, lo cual mucha gente no sabe hacer)...

...En fin, que me vi en la tesitura de desarrollar un programa sencillo de monitor serie que pudiera hacer exclusivamente lo que necesito, y como sigo fiel a mi vetusto Visual Basic 6.0, en una mañana (por suerte sigo de vacaciones hasta el jueves) desarrollé un interface operativo, con ventanas de texto de igual tamaño y las funciones básicas de transmisión y recepción, que para no alargar demasiado mostraré en el siguiente mensaje...

Un saludo a todos