1. INGENIERÍA INVERSA
Y CRIPTOANÁLISIS
José Enrique Alvarez Estrada
jeae@prodigy.net.mx
ICQ 31463788
Yahoo! Messenger: leonardo_da_vinci_mx
www.geocities.com/leonardo_da_vinci_mx/
Nadie pone en duda la importancia de la ingeniería como disciplina del conocimiento humano. Pero
pocas personas saben que esta disciplina posee una contraparte: la llamada ingeniería inversa.
El objetivo de la ingeniería, es desarrollar la solución a un problema a partir de la nada. En cambio,
la ingeniería inversa propone solucionar ese mismo problema, pero a partir de alguna tecnología
existente, cuyo funcionamiento no se conoce (al menos no totalmente), pero que se sabe tiene el
potencial de resolverlo total o parcialmente.
Si bien no existe una licenciatura en ingeniería inversa, es un hecho que muchos ingenieros
dedican su vida profesional a esta disciplina. Pero, curiosamente, muy poco o nada se habla de ella
en las currículas universitarias, y no se les enseña a los nuevos ingenieros. De hecho, en muchos
círculos el hablar de ingeniería inversa todavía es un tabú, y si bien se sabe y se acepta que la
mayor parte de las empresas la utilizan, nadie quiere reconocerlo abiertamente.
El objetivo de este artículo es divulgar la importancia de esta disciplina, equipararla con el
criptoanálisis y tratar de sacarla del oscurantismo en el cuál se encuentra, dándole el nivel y la
relevancia que realmente tiene, demostrando que desde el punto de vista de los ingenieros que
aspiran dedicarse a desarrollar su profesión, la ingeniería inversa puede ser tan interesante, o más,
que la ingeniería tradicional.
Historia de la ingeniería inversa
La ingeniería inversa es tan antigua como la ingeniería. Podemos pensar en dos tribus rivales que se
enfrentan en una guerra, pero una de ellas posee una tecnología más avanzada que la otra. Al final
de cada batalla, los miembros de la tribu que se encuentra en desventaja tecnológica, de seguro
juntaban todos los artefactos de guerra arrebatados al rival, con el objeto de estudiar la manera en
que fueron desarrollados, y con la idea de crear otros que al menos sean equivalentes en
características, si no mejores.
En un contexto menos violento, podemos ver la presencia de la ingeniería inversa a partir del
surgimiento del comercio: cuando un producto desconocido en una cierta latitud llegaba
proveniente de otra, ese producto sin duda era estudiado, tratando de desentrañar los secretos de su
construcción, con la idea de crear uno idéntico o perfeccionado.
Pero el verdadero crecimiento de la ingeniería inversa ocurre como consecuencia natural de la
Revolución Industrial: en esta época de fuerte expansión tecnológica, cada inventor no podía perder
de vista los desarrollos creados por sus colegas, estudiarlos en profundidad y tratar de encontrar la
manera en que éstos funcionaban. En este periodo, sin duda, la ingeniería inversa tuvo una
ferocidad increíble, lo que dio pie, en buena medida, al nacimiento y desarrollo de las leyes de
patentes, los derechos reservados, el copyright y demás esquemas de protección a la propiedad
intelectual.
En la actualidad, las leyes y reglamentos de casi todos los países prohíben la mayoría de las
prácticas de ingeniería inversa, por considerar que atentan contra la propiedad intelectual. Sin
embargo, hay países ampliamente conocidos por practicarla, como es el caso de Japón, que ha
desarrollado toda una industria y una tecnología florecientes, a partir de la ingeniería inversa que
2. después de la II Guerra Mundial ha practicado a cuanto producto extranjero de calidad ha caído en
sus manos.
De hecho, es bien conocida la anécdota de que durante las décadas de los sesenta y setenta, se
prohibía a los japoneses que asistían a ferias indsutriales en Estados Unidos y Europa, llevar
consigo cámaras fotográficas y videográficas, para evitar que un año después de su visita liberaran
tecnologías equivalentes, pero con un mayor grado de perfección y un costo mucho menor. Sin
embargo, los ingenieros japoneses reemplazaron sus cámaras fotográficas por papel y lápiz,
elaborando croquis y dibujos detallados de lo que veían.
A pesar de todas estas prohibiciones y restricciones, es obvio que la ingeniería inversa es una
práctica común en las industrias que desarrollan tecnología. Si no, ¿cómo se puede explicar que,
con meses de diferencia, un software incluya filtros de importación y de exportación para los
formatos de archivo que su competencia usa? O bien existe un acuerdo entre ambos competidores
para el intercambio de información reservada sobre sus formatos (situación poco creíble, y que sin
duda trascendería a los medios de comunicación), o se emplean técnicas de ingeniería inversa para
decodificar la forma en que la competencia almacena la información.
Definición de ingenieria inversa
Hasta ahora, hemos utilizado el término ingeniería inversa sin una definición clara de lo que es:
vamos construyéndola. Podemos decir, en términos generales, que ingeniería inversa es el proceso
mediante el cual una tecnología o producto es desarmado, con el fin de conocer los componentes
que lo integran y la forma en que éstos interactúan, para lograr finalmente una comprensión cabal
de su modo de funcionamiento, con el objetivo probable de construir una tecnología similar. La
ingeniería inversa toma un producto cuyo formato presenta un bajo grado de abstracción, y obtiene
una nueva presentación del mismo, con una abstracción mayor.
Sin duda, cada rama del conocimiento ha desarrollado sus propias técnicas de ingeniería inversa.
Por ejemplo, en el caso de la química, el análisis espectrográfico de los componentes que forman
una substancia (digamos, un fármaco) puede utilizarse para crear una substancia similiar. En la
mecánica, el desensamblado de un mecanismo permite al ingeniero ver las partes que lo integran,
sus medidas, los materiales de que está hecho, etc. de modo que esté en condiciones de crear un
clon del mismo.
En las ingenierías aeronáutica y naval suceden cuestiones similiares: tómese como ejemplo la
película La caza al Octubre Rojo, donde el ejército norteamericano realiza todo tipo de esfuerzos
para hacerse de un submarino ruso que instrumenta una nueva tecnología de navegación
subacuática. Se conocen casos de aeronaves de cualquiera de las dos superpotencias, que han sido
capturadas por la otra para analizar su funcionamiento. El reciente caso del hundimiento de un
submarino ruso, y las dificultades que las autoridades de ese país ponían al rescate internacional,
responden también a la colocación de barreras para evitar que el enemigo observe tecnologías
clasificadas.
La computación no es una excepción a todo lo anterior, y también ha desarrollado técnicas de
ingeniería inversa, mismas que se pueden clasificar en dos categorías:
Ingeniería inversa de hardware, que tiene más que ver con la disciplina de la ingeniería
electrónica, que propiamente con las ciencias de la computación.
Ingeniería inversa de software, que es realmente la que nos interesa en el contexto de este
artículo.
Dentro de la ingeniería inversa de software, podemos subclasificar en tres categorías: la ingeniería
inversa de código fuente, la ingeniería inversa de código objeto y la ingeniería inversa de archivos.
3. Ingeniería inversa de código fuente
Se aplica la ingeniería inversa de código fuente, cuando se tienen los códigos fuentes de un cierto
programa, pero éstos se encuentran parcial o totalmente indocumentados, probablemente por
modificaciones o parches que se le han realizado con el paso del tiempo.
El objetivo de esta técnica de ingeniería inversa es rehacer los planos del sistema, o sea, obtener
todos aquellos diagramas que nos permitan entender cómo fue que el sistema fue analizado,
diseñado y construido.
Esto tiene mucho que ver con los llamados sistemas heredados o legacy systems, es decir, software
en el que un nuevo grupo de ingenieros tiene que hacer frente a labores de extensión de
funcionalidad y/o mantenimiento de un sistema creado por otro grupo de ingenieros, que
probablemente no documentó su trabajo.
Este es el tipo de ingeniería inversa del que existe más documentación disponible, a grado tal que la
IEEE (Institute of Electric and Electronic Engineers) publica revistas especializadas sobre el tema.
Desde los puntos de vista ético, social, económico, etc. se considera como la ingeniería inversa más
aceptable.
Ingeniería inversa de código objeto
El segundo tipo de ingeniería inversa, la de código objeto, busca obtener a partir de un programa
compilado, códigos fuentes en un lenguaje de alto nivel, probablemente aquél en el que se
desarrolló originalmente.
En primera instancia, este tipo de ingeniería inversa puede resultar benéfico, siempre que se aplique
a un sistema del cuál se es legalmente propietario, pero del que por alguna razón ya no se tiene
código fuente, y se desea obtener dicho código fuente para hacerle modificaciones, extensiones o
simplemente para recuperar de él las reglas del negocio.
Hasta aquí, sería algo similar a la práctica para el código fuente explicada anteriormente. El
problema es que si se tiene una herramienta que permita practicar este tipo de ingeniería inversa,
nada impide aplicarla a programas compilados de los que uno no es propietario, es decir, que sólo
se posee la licencia de uso (y no los derechos de autor) del mismo.
Alrededor de esta práctica se han creado verdaderos mitos, relacionados con hackers y crackers que
pueden obtener el código fuente de productos muy sofisticados, y aprovecharlo en su propio
beneficio económico, o bien utilizarlo para la creación de virus y la violación de patentes. Sin
embargo, hay muchas ocasiones en las cuales estas prácticas resultan benéficas, en vez de dañinas:
un buen ejemplo pudiera ser la creación de drivers para el manejo de dispositivos hardware en un
sistema operativo para el cuál no existen (i.e. Linux), a partir de información obtenida por
ingeniería inversa del driver que el fabricante haya liberado para otro sistema operativo (i.e.
Windows y/o DOS).
Resumiendo, la ingeinería inversa de código objeto busca obtener las reglas de negocio o las reglas
de funcionamiento de un software, a partir del código compilado del mismo, para luego
seguramente crear un clon, posiblemente gratuito o distribuido bajo licencia pública general GNU,
que se ejecute en la misma plataforma, o en otra distinta.
Ingeniería inversa de archivos
En tercer lugar, cabe explicar la llamada ingeniería inversa de archivos. Aquí no se trata de obtener
información sobre el programa en sí (se trate de su código fuente o de su código objeto), sino más
bien tratar de entender cómo es que el software almacena la información en disco, con el objetivo
probable de abrir dichos archivos con nuevo software, y permitir así la compatibilidad.
4. La ingeniería inversa de archivos es, desde el punto de vista legal, una de las más toleradas, puesto
que finalmente lo único que se pretende con ella es comprender la manera en que la información
que un usuario posee está siendo almacenada en un sistema.
Resulta muy importante también en el contexto de los legacy systems, donde archivos creados con
software muy antiguo pueden ser migrados a nuevos sistemas (por ejemplo, sistemas monolóticos
que se migran a arquitecturas cliente/servidor): la única forma de obtener información del archivo
es a través de técnicas de ingeniería inversa, si no se posee la documentación correspondiente.
Ingeniería inversa y reingeniería
Es habitual encontrar, en la poca literatura que trata de estos temas, el uso indiscriminado de los
términos reingeniería e ingeniería inversa, pero esto es totamente incorrecto y amerita una
aclaración.
La reingeniería es un concepto que nace de la mano de la ingeniería industrial, y que propone la
modificación radical de procesos de producción y/o de administración, para realizar las mismas
labores con menos personas, menos recursos y en menos tiempo.
Por supuesto, una parte de una reingeniería de procesos puede ser la reingeniería del software que
soporta dicho proceso: se parte de un sistema que realiza una labor, y se pretende modificar su
funcionamiento para que se adapte a los cambios del proceso. Aquí aparece la ingeniería inversa,
como una disciplina que apoya a la reingeniería, al permitir que se conozcan las reglas del negocio
codificadas en el sistema de cómputo, para a partir de ellas construir un sistema que soporte el
nuevo proceso.
Se trata por tanto de dos disciplinas del conocimiento distintas, si bien complementarias entre sí.
Ingeniería inversa y criptoanálisis
Otra disciplina del conocimiento muy antigua, y que también se acostumbra a presentar asociada a
la ingeniería inversa, es el criptoanálisis.
El criptoanálisis y la criptografía forman una disciplina, que en forma general se conoce como
criptología. La criptografía busca el envío de un mensaje a través de un medio probablemente
inseguro, de tal forma que sólo el receptor legítimo del mensaje pueda leerlo, mientras que a
cualquier usurpador (receptor ilegal) que se encuentre en la trayectoria del mensaje le resulte
imposible (o al menos muy difícil) acceder a su contenido. Por ejemplo, el emperador romano Julio
César usaba una clave (a la sazón llamada clave Cesárea) que consistía en reemplazar cada letra por
la tercera letra del alfabeto, después de ella misma. El criptoanálisis es, por el contrario, la
disciplina que busca la decodificación de un mensaje que ha sido previamente encriptado, con el fin
de hacerlo visible a personas distintas a su receptor legítimo.
El criptoanálisis y la ingeniería inversa comparten, en el fondo, una filosofía común: permitir que
una persona tenga acceso a una información no destinada a él. Además de esto, comparten en muy
buena medida las técnicas que aplican a la solución de problemas.
Pensemos, por ejemplo, lo que sucede cuando un criptoanalista posee un mensaje cifrado, y el
mismo mensaje parcial o totalmente descifrado. A partir de ambos, puede tratar de encontrar la
manera (el algoritmo) mediante el cual se encriptó la información. En ingeniería inversa sucede
algo similar: si tenemos un programa con la capacidad de guardar información en un cierto formato
de archivo, y nosotros tenemos acceso a dicho programa, de tal forma que podemos grabar nuestra
propia información (el mensaje sin cifrar) y revisar cómo quedó una vez guardado (el mensaje
cifrado), entonces estaremos en posibilidad de determinar el algoritmo que almacena la
información.
Otra técnica que se puede emplear tanto en criptoanálisis como en ingeniería inversa, son los
5. llamados algoritmos de fuerza bruta. Estos algoritmos prueban todas las posibles combinaciones de
la clave de encriptación, hasta obtener un mensaje desencriptado que tenga sentido. En el caso de la
ingeniería inversa, esto involucra modificar la información que se encuentra almacena en un
archivo, y desplegarla para ver la forma en que los datos originales cambiaron. En ambos casos, se
aplica cuando no se posee inicialmente el mensaje encriptado, o la posibilidad de acceder al
software para crear nuevos archivos.
Entre los ataques con mensaje totalmente descifrado, y los ataques de fuerza bruta, existen
innumerables técnicas intermedias (y si no existen, se pueden desarrollar) que permitan la
decodificación y la ingeniería inversa del archivo a partir de mensajes parcialmente descifrados, o
bien de acceso parcial al programa que crea los archivos.
Champollion y la Piedra Rosetta
Un ejemplo histórico interesante de ingeniería inversa y criptoanálisis, es el desciframiento de la
llamada Piedra Rossetta. La Piedra Rosseta es un decreto del rey Ptolomeo V Epífanes, que data
del 196 antes de Cristo, donde aparece el mismo mensaje escrito en jeroglíficos, en demótico y en
griego, y que fue encontrada por los soldados de Napoleón durante su campaña de 1897, mientras
construían un fuerte.
Utilizando la sección en griego como una clave, se demostró que los jerogríficos no eran símbolos
decorativos, sino que representaban un lenguaje. Varios matemáticos de la época, entre ellos el
inglés Thomas Young (1773−1829) abordaron el trabajo de descifrarlos. Pero fue el egiptólogo
francés Jean−François Champollion (1790−1832) quien los decodificó en 1822, descubriendo la
escritura de un lenguaje que resultó ser el ancestro del cóptico, el conocido lenguaje del Egipto
cristiano medieval.
Champollion demostró que los jeroglíficos son un sistema de escritura no alfabético, que almacena
sólo las consonantes del antiguo lenguaje egipcio, usando una mezcla de ideogramas (símbolos que
representan palabras) y fonogramas (símbolos que representan un sonido). Los signos se escriben
usualmente de izquierda a derecha, pero sin puntuación ni espacios entre las palabras; la direccion
de la escritura se indica por la dirección de los signos que marcan el inicio del texto.
Muchas palabras terminan con signos pictóricos, llamados determinativos, los cuales muestran qué
tipo de palabra es. Por ejemplo, la palabra para gato (miw) termina con un signo mostrando un
gato. Cuando la palabra es un nombre femenino, el determinativo es una mujer sentada, que se
agrega para evitar confusiones de género.
Cuando Champollion descifró el código, puso a nuestro alcance 3000 años de textos egipcios
escritos, pero eso fue sólo el comienzo de la "lectura" del antiguo Egipto. El lenguaje escrito es sólo
parte del "código cultural", tan sutil y complejo como cualquier código de cifrado de mensajes
secretos. A lo largo de 3000 años el lenguaje cambió, como lo hizo su contexto social e histórico, y
diferentes versiones del lenguaje y de la escritura se usaron para distintos propósitos (como sucede
hoy en día). Los jeroglíficos se reservaron para propósitos monumentales y rituales, mientras que
textos más cotidianos, que tratan aspectos que van desde el comportamiento diario hasta tratados
médicos y matemáticos y textos rituales, fueron escritos en dialectos más corrientes. La historia
detallada de la ingeniería inversa de Champollion a la Piedra Rosetta ha dado pie a numerosos y
apasionantes libros, y sin duda desencadenó, junto con el descubrimiento de la tumba de
Tutankhamen, el furor por todo lo egipcio.
Técnicas basadas en fuerza bruta
Para ejemplificar cómo trabajaría un criptoanálisis basado en fuerza bruta, pensemos lo siguiente:
supongamos que se utiliza una clave, compuesta por 8 bits, que se le aplica por medio de la función
lógica XOR a todos los bytes que integran un mensaje. Se puede modelar esto diciendo que el
mensaje saliente, o mensaje encriptado (Me), es el resultado de aplicar una función de
6. transformación al mensaje entrante o mensaje desencriptado (Md), con una clave (C).
Me = F(Md, C)
11001100 = xor(01100110, 10101010)
Un criptoanalista, empleando técnicas de fuerza bruta, simplemente probaría todos los símbolos
posibles del alfabeto como claves, hasta encontrar un posible mensaje que resulte coherente.
Dependiendo del tamaño de la clave C, esto puede dar pie a una explosión combinatoria que
requiera de un enorme poder de cómputo, a veces tan grande que simplemente no puede resolverse
en un tiempo razonable (problemas computacionalmente insolubles). Sin embargo, para el ejemplo
que acabamos de plantear (una clave de 8 bits), resulta bastante factible el probar todas las
combinaciones, que sólo son 256. Aumentando el tamaño de clave a 40 ó a 128 bits, como hacen
los algoritmos de encriptación usados en Internet, las cosas resultan mucho más difíciles.
Criptoanálisis e ingeniería inversa conociendo el
mensaje desencriptado
Si se posee el mensaje decodificado, y su contraparte codificada, las labores de ingeniería inversa o
de criptoanálisis se simplifican enormemente. Se trata aquí de determinar la función de
transformación (F) que ha hecho pasar de un valor decodificado a otro codificado, pero se posee
una cantidad importante de valores Me y Md que permitan definir la función.
En el caso de la ingeniería inversa, si se tiene acceso al programa que guarda la información, la
labor es más fácil. Pensemos por ejemplo en el siguiente programa en Pascal, que es el equivalente
a Md:
program aaa;
var
i, j : byte;
begin
j := 0;
for i := 1 to 10 do
j := j + 10;
end.
A partir de este código, se puede compilar la aplicación, y se obtiene el siguiente código objeto (el
equivalente a Me):
XOR A,A
MVI B,1
ADI A,10
ADI B,1
CMP B,11
JNZ 4
Puede observarse, por simple inspección, que la asignación del valor 0 a la variable j se lleva a cabo
mediante un XOR de A consigo mismo (lo cuál siempre produce cero), y que el registro B está
actuando como un contador que se inicializa en 1. Posteriormente, se incrementa el valor de B en
10 (como en la línea j := j + 10), luego se incrementa B en 1 (el incremento de la variable
contadora), se compara con 11 (la condición de salida de la sentencia FOR) y en caso de que no
coincida (el resultado no fue cero) se salta a la línea 4. Por tanto, para álguien que pretenda obtener
la forma en que el compilador trabaja (creando lo que se denomina un desensamblador), esta
información es sumamente valiosa.
Pongamos otro ejemplo: analizamos la manera en que se lleva a cabo la ingeniería inversa de
archivos, cuando se posee el programa que genera dichos archivos. La técnicas usada
fundamentalmente es la inspección. En primer lugar, se usa la opción que proporciona dicho
programa para construir un archivo nuevo, y el archivo es guardado tal cual, sin agregarle ninguna
7. información. Esto nos proporciona un parámetro inicial, respecto al formato que el archivo tiene:
todas aquellas partes del archivo invariantes, o todas aquellas partes del archivo configuradas con
valores por default.
Como segundo paso, se procede a cambiar los valores por defecto que posee el programa en su
configuración. Por ejemplo, el tamaño X,Y de un archivo gráfico, la orientación y el tamaño de
papel si se trata de un archivo de procesador de texto, etc. Con esto, podemos separar los elementos
invariantes del archivo de los elementos de configuración, y lo que obtendremos finalmente es una
representación bastante aproximada de la estructura de encabezado del mismo.
A partir de este punto, comenzamos con un proceso de agregación de nuevas opciones: si se trata de
un procesador de texto, agregamos palabras, y vemos la manera en que dichas palabras están siendo
codificadas en el archivo, después integramos estas palabras en párrafos, y así sucesivamente; si se
trata de un programa de manipulación de bitmaps, agregamos pixeles (preferiblemente en las
esquinas superior izquierda e inferior derecha, para indicar el inicio y el final de la imagen) y
vemos la manera en que éstos son codificados.
En el caso de archivos gráficos que representan imágenes bidimensionales, algo que se debe
determinar con claridad es si se trata de archivos que codifican la imagen con un formato true color
(es decir, que cada pixel codifica la verdadera intensidad de cada color), o si utilizan una tabla de
localización de color ó CLUT (Color Look Up Table), en donde cada pixel es un índice a los
elementos de color de dicha tabla. En ambos casos, debemos determinar también el modelo de
color que se está usando: si se trata de un modelo de síntesis aditiva como RGB, o de un modelo de
síntesis substractiva como CYMK, aunque normalmente esto es un parámetro de configuración del
programa, y por tanto no resulta difícil de percibir.
Algo que no resulta tan fácil es determinar la alineación de los pixeles: si éstos aparecen renglón
por renglón o columna por columna. Si ya pudimos determinar esto, lo siguiente es saber si el
formato gráfico usa algún tipo de algoritmo de compresión para los pixeles que integran la imagen
(o para las letras, si se trata de un procesador de texto, o para las muestras, en el caso de audio
digitalizado).
Para aquellos formatos que usan compresión RLE (Run−Length Encoding), esto es relativamente
fácil: basta con ir incrementando el número de pixeles consecutivos de un mismo color, e ir
observando la forma en la cuál se comportan los bytes en el archivo. Generalmente, conforme se
aumenten los pixeles consecutivos del mismo color, se observará el incremento de un índice, y la
permanencia en el mismo valor del elemento siguiente, donde el primero codifica el número de
pixeles repetidos, y el segundo su intensidad de color. Este esquema normalmente recurre a un
valor o byte centinela, que se emplea para diferenciar aquellos pixeles normales de los valores que
almacenan el número de repeticiones RLE. Generalmente, se emplean dos técnicas al respecto: una
de ellas es reservar un símbolo del alfabeto como centinela, y otra es que el propio valor del pixel
indique si se trata de un centinela o no, dividiéndolo en dos rangos (i.e. 0−15 indica valor directo,
16 en adelante indica centinela).
Para conocer la longitud máxima que puede tener una corrida de bits repetidos codificados con
RLE, se va incrementando el número de bits, en espera de aquel en el cuál el centinela ya no
alcance a guardar todos los elementos, y se requiera de dos corridas RLE consecutivas.
Criptoanálisis e ingeniería inversa sin conocer el
mensaje desencriptado
En muchas ocasiones, el criptoanalista no posee el mensaje desencriptado como ayuda a su labor.
Por ello, algunas de las técnicas usadas por los criptoanalistas y por la ingeniería inversa han tenido
que recurrir a otros enfoques, como estudiar características propias del dominio del problema que
se está atacando.
8. La clave aditiva, como la usada por Julio César, y otros sistemas de criptografía sencillos (los
llamados sistemas de encriptación por substitución), son susceptibles de analizarse basándose en la
estadística. De hecho, la criptografía fue una de las grandes motivaciones para el desarrollo de la
ciencia de la estadística (que inicialmente trataba problemas de estado, incluyendo el envío de
mensajes seguros y la decodificación de los mensajes enemigos), y a la vez es uno de los logros
cumbre de la misma.
Por ejemplo, en el caso del criptoanálisis, si se tiene la certeza de que el mensaje enviado es texto,
puede recurrirse a técnicas de substitución por frecuencia de ocurrencia de los caracteres: en todos
los idiomas hay caracteres que se ocupan con más frecuencia que otros, y los criptoanalistas han
desarrollado histogramas (diagramas de frecuencia) que indican la ocurrencia promedio de cada
carácter para una lengua dada. A partir de esta información, se puede intentar un ataque estadístico
que, sin conocer siquiera la función o la clave de encriptación, nos devuelva el mensaje
desencriptado. Es un hecho conocido que el inglés (igual que en muchos otros lenguajes humanos)
es un idioma muy poco aleatorio. En el trasncurso de cualquier texto en inglés substancialmente
largo, las letras aparecen con una frecuencia muy predecible. La Tabla 1 es una medición de las
frecuencias relativas de las letras en textos en inglés.
Letra Frecuencia (%) Letra Frecuencia (%)
a 8.167 n 6.749
b 1.492 o 7.507
c 2.782 p 1.929
d 4.253 q 0.095
e 12.702 r 5.987
f 2.228 s 6.327
g 2.015 t 9.056
h 6.094 u 2.758
i 6.966 v 0.978
j 0.153 w 2.360
k 0.772 x 0.150
l 4.025 y 1.974
m 2.406 z 0.074
Tabla 1Frecuencia de ocurrencia de los caracteres en el idioma inglés.
Se observa que la "e" es la letra con mayor frecuencia de ocurrencia (12.7%). Existe también
información estadística de la frecuencia de bigramas, o sea, grupos de dos letras, y trigramas
(grupos de tres letras).
Si el criptoanalista sospecha que el mensaje está escrito con un cifrado monoalfabético, donde cada
letra del texto está representada por un símbolo distinto), y si se posee una gran cantidad de texto
cifrado, se pueden computar las frecuencias de las letras en el mensaje encriptado, y substituirlas de
acuerdo a la tabla. Si se trata de una clave aditiva (clave Cesárea), con sólo identificar la "e" ya se
encontró toda la clave. Virtualmente, todos los criptosistemas propuestos en el siglo XIX probaron
ser susceptibles a ataques estadísticos, cada vez más sofisticados.
Empleo de técnicas de IA
La ingeniería inversa y el criptoanálisis son, sin duda, problemas apasionantes, que llaman la
atención de los aficionados a las matemáticas y a la ingeniería. Sin embargo, es una labor
9. intelectual altamente desgastante y muy demandante de tiempo, lo cual involucra la necesidad de
crear herramientas que la apoyen.
El problema de estas herramientas es que, si emplean únicamente ataques por fuerza bruta, se
enfrentan a difíciles barreras de computabilidad, debido a la explosión combinacional que ya se
mencionó, e impidiendo que una computadora (sea del tamaño que sea) resuelva el problema en un
tiempo razonable.
Por ello, los científicos en computación buscan formas de darle la vuelta al problema. Casi todas
ellas se basan en conocimientos previos que se tienen de casos similares que han sido solucionados,
o bien del reconocimiento de patrones de símbolos que se repiten recurrentemente en el proyecto
que se está tratando de resolver. En ambos casos, las técnicas desarrolladas por la Inteligencia
Artificial (IA), una disciplina de las ciencias de la computación, resultan extremadamente útiles.
Podemos señalar, entre estas técnicas: búsquedas en espacios de soluciones, reconocimiento de
patrones, visión por computadora, redes neuronales artificiales, sistemas expertos, sistemas con
capacidad de aprendizaje, etc. El empleo correcto de estas técnicas permite la automatización de
una buena parte de las labores de ingeniería inversa y de criptoanálisis.
Conclusiones
Conforme pasa el tiempo, y hay mayor cantidad de legacy systems en el mercado en espera de ser
actualizados, mayor es la importancia de la ingeniería inversa de software. Así mismo, conforme
las transacciones en Internet se hacen más populares, e involucran cantidades crecientes de dinero,
poner a prueba los algoritmos de encriptamiento existentes mediante nuevas técnicas de
criptoanálisis, es la única manera de asegurar su confiabilidad.