La última vez hablamos de algunos métodos criptográficos que se usaban en la más o menos antigüedad. Eran todos ellos métodos relativamente fáciles de explicar, y podían ser útiles en diversas ocasiones, pero para todos ellos existía una manera de romperlos: incluso aunque el emisor y el receptor no hubieran cometido errores, era posible, siendo relativamente hábil, llegar al mensaje original. Sin embargo, el sistema que tratamos hoy es más bien todo lo contrario: si no se cometen errores, tratar de recuperar el mensaje en texto plano puede ser prácticamente imposible. ¿Escéptica ante la posibilidad de que hayamos resuelto el problema del envío seguro de mensajes la segunda vez que hablamos de criptografía? Sana actitud la tuya.
Te presento al protagonista de la historia de hoy, el one-time pad (OTP), también conocido como cifrado de Vernam. Para usarlo necesitaremos que nuestros mensajes y nuestras claves estén formadas únicamente por ceros y unos (¿te preguntabas dónde estaban las matemáticas?). Esto no debería ser un problema en un mundo como el de hoy, en el que todos nuestros ordenadores y demás parentela representan internamente letras, números y demás en forma de bits, que solemos imaginar como ceros y unos. Por ejemplo, ahí tenemos los estándares ASCII y Unicode, que te dicen exactamente qué combinación de cuántos bits representan una letra, número, salto de línea o emoji. Así que puedes traducir tus mensajes privados a uno de estos estándares y cifrarlos con el OTP; quien descifre deberá volver a traducir de vuelta a alfabetos más familiares.
Para ver cómo funciona el OTP, es conveniente introducir una “operación” que hacer con estos ceros y unos. Técnicamente, esta operación tendría una tabla asociada, como la suma y la multiplicación que conocemos desde pequeñinos, pero puede que te resulte más fácil pensar en ella sin la tabla. A fin de cuentas, sólo hay que saber lo que hace la operación en dos números: 0, y 1. Y la regla es la siguiente: si tú sumas (voy a llamar a esta operación “suma” a partir de ahora, ¿vale?; es más cómodo) dos números \(a\) y \(b\) que pueden valer bien 0 o 1, el resultado es \(a\) si \(b\) es igual a 0, y “el número que no es \(a\)” si \(b\) es igual a 1. Puedes pensar en ello como que empiezas con \(a\), y luego \(b\) lo cambia si y sólo si es 1. Esta “suma” la representaremos por hoy con el símbolo \(\oplus\); así, la tabla de esta suma resulta ser
Esta operación le es bastante conocida a bastante gente. En matemáticas se llama suma módulo dos, lo que explica que me sea cómodo llamarla “suma”; algún día hablaremos de por qué. También aparece en lógica e informática, donde sería conocida como o exclusivo o XOR, lo que representa otra manera de ver la operación: el resultado de la operación es 1 si el primer o el segundo operando, pero sólo uno de los dos, es igual a 1; si no, el resultado es 0. Yo lo he explicado basándome en algo más de andar por casa, como son los interruptores: si tienes una lámpara controlada por un interruptor, puedes pensar en los estados “lámpara encendida” y “lámpara apagada” como ceros o unos; sumar \(a \oplus b\) es partir de una lámpara en el estado \(a\) y dejarla tal cual si \(b\) es 0, o darle al interruptor si \(b\) es 1. Puedes tomarte un tiempo para pensar en estas maneras de entender la operación antes de seguir.
¿Lista? Bien, porque vamos a seguir con una generalización natural de esta operación. Imagínate que no tienes sólo un cero o un uno, sino que tienes una ristra de ellos; por ejemplo, la que obtendrías después de haber traducido un mensaje a ASCII. Al mismo tiempo, tienes otra cadena de ceros y unos de la misma longitud; por ejemplo, la de tu clave. Bien, puedes sumar estas dos listas, digamos, número a número: puedes conseguir una lista de la misma longitud, donde el número en primera posición es el XOR de la primera entrada de tu mensaje con la primera entrada de tu clave. Por ejemplo, si tu mensaje fuera 10100111011010110 y tu clave fuera 00101101010110010, su “suma” valdría
Realmente es como sumar números de muchos dígitos, pero más fácil porque con esta operación no hay que llevar nada. Ya ves, parece más fácil que las matemáticas de primaria. Igual que puedes “sumar”, puedes “restar”. De hecho, es literalmente igual que sumar. Si tú ahora a tu número suma 10001010001100100 le quieres restar lo que le sumaste, es decir, 00101101010110010, lo que tienes que hacer es volverlos a sumar; el resultado acaba siendo
que es lo que teníamos de partida.
Veamos entonces cómo funciona el OTP en general. Supongamos que los británicos Alice y Bob quieren intercambiar información de manera secreta: Alice tiene un mensaje en texto plano \(M\) que enviar a Bob, en forma de unos y ceros, y ambos poseen una clave \(K\). Lo que Alice hace entonces es calcular el mensaje cifrado \(C=M \oplus K\), y enviar esa información a Bob. Para recuperar el mensaje original, Bob sólo tiene que sumarle la clave a lo que le llegó, es decir, calcular \(C \oplus K\); esto viene a ser igual a \(M \oplus K \oplus K\), que como ilustramos antes con un ejemplo es a su vez igual a \(M\). Si alguien interceptase el mensaje cifrado \(C\) (a esta persona se le suele llamar Eve, por “eavesdropper” y porque tienen sentido del humor), lo único que tendría sería \(M \oplus K\); de ahí no tiene forma de separar el mensaje en texto plano original, porque no tiene la clave. Por lo que, al menos a priori, parece que el sistema funciona.
De hecho, se puede decir más que “funciona a priori”. El one-time pad es lo que se conoce como un criptosistema de secreto perfecto. La idea es, más o menos, que para un observador externo, que quiere conocer el mensaje original pero no tiene acceso a él, conocer el mensaje cifrado no le sirve de absolutamente nada. Esto supondría una diferencia con respecto a otros de los criptosistemas que comentamos la última vez: conocer el mensaje cifrado puede proporcionarte información acerca del mensaje original, por ejemplo estudiando la frecuencia con la que aparecen las letras en el cifrado y comparándola con la frecuencia normal con la que aparecen. Sin embargo, para el OTP esto no es así: interceptar el mensaje cifrado no te dice nada. A fin de cuentas, ¿qué obtienes, si no un amasijo de ceros y unos cuya estructura original (la del mensaje en texto plano) se puede haber ido al garete al sumarle la clave? Tal vez algún día podamos tomarnos un tiempo para ver esta noción de forma algo más rigurosa, y ver por qué el OTP tiene secreto perfecto, pero hoy no quiero entrar más en detalle en el tema.
La idea es que el OTP es seguro. ¿Sigues sin creértelo? Tendrás tus motivos para ello, supongo. Tal vez estés pensando que no habías oído del one-time pad antes de hoy, y que cuando la gente habla de criptografía suelen usar otros términos que no he usado hasta ahora, por lo que no tendría sentido que se hubiera solucionado el problema del todo con el OTP. Y tendrías razón, porque hay un problema escondido en mi descripción del OTP; un problema lo suficientemente problemático (soy de ciencias) como para echar por tierra nuestras esperanzas de comunicaciones seguras con el OTP.
Piensa en la situación de Alice y Bob: quieren enviar un mensaje, y para ello Alice lo cifra con una clave. Bien, pero luego Bob debe usar esa misma clave para descifrarlo: ¿cómo la conoce? Se la habrá enviado Alice, ¿pero cómo? Si la envía sin cifrar, es posible que alguien la haya interceptado, por lo que cualquier mensaje cifrado con esa clave es vulnerable de ser interceptado y descifrado. Luego la habrá cifrado, pero ¿con qué clave? ¿Con otra? ¿Y cómo conoce Bob esta segunda clave? Estaríamos en las mismas. ¿Tal vez haya cifrado la clave consigo misma, entonces? Pero esto sólo suena ingenioso hasta que lo piensas en serio. Básicamente, para poder enviar un mensaje de forma segura con el OTP es necesario poder enviar la clave de forma segura, pero si ya tuviésemos un sistema así de seguro, ¿por qué mandar la clave para luego usar el OTP, en lugar de mandar el mensaje directamente?
Que no cunda el pánico. Es posible que Alice y Bob hayan conseguido, por ejemplo, acordar en persona el uso de una clave, y luego ya usarla cuando necesiten intercambiar algún mensaje. Vale, bien. Pero, ¿han acordado una clave para cada mensaje que puedan enviar con tanta antelación? ¿Tienen Alice y Bob una libreta con cientos de claves, para usar con respectivos cientos de mensajes que quieran intercambiar? Eso puede ser un problema si alguien consiguiese acceder a los documentos de Alice o Bob y encontrar dichas claves.
Llegados a este punto, la opción más interesante parece aquélla que mucha gente tiende a seguir, a pesar de las recomendaciones de los expertos en seguridad: ¿y si reutilizo las claves? No hay que memorizar o apuntar nada más que una o pocas claves, que tal vez se puedan guardar de forma más sencilla que una libreta llena de claves. El problema es que, y no hay otra manera de decirlo, esta estrategia se carga la seguridad del OTP. Para verlo, supongamos que Alice y Bob han acordado una clave \(K\). Alice le envía a Bob un mensaje \(A\) (por \(A\)lice), cifrado con la clave \(K\); Bob, en respuesta, le envía un mensaje \(B\) (por \(B\)urro) cifrado con la misma clave \(K\). Imagínate ahora que una tercera persona, Eve, intercepta ambos cifrados: lo que obtiene es \(A \oplus K\) y \(B \oplus K\). Bien, ahora viene la jugada: Eve suma ambos mensajes cifrados. ¿El resultado?
\(A \oplus K \oplus B \oplus K = A \oplus B\)
A primera vista, la situación de Eve no parece haber mejorado mucho, porque sigue teniendo una combinación de ceros y unos que no le da directamente ningún mensaje. Pero esta combinación no involucra para nada la clave \(K\): el resultado depende únicamente de los dos mensajes. Piénsalo: ¿cómo obtendrías \(A\) a partir de \(A \oplus B\)? Tendrías que sumarle \(B\), pero no lo conoces. Ahora, esta vez sabes que \(B\) representa un mensaje, así que puedes intentar sumar palabras y ver qué pasa. Un ejemplo: imagínate que \(B\) empieza por Hola. Puedes coger el primer trozo de \(A \oplus B\), el que represente cuatro letras; si le sumases el mensaje Hola, traducido a ceros y unos, sería como restarle ese Hola, y recuperarías las primeras cuatro letras del mensaje \(A\). Usa varias palabras, en distintas partes del mensaje, y usando los fragmentos que vayas descifrando como contexto para el resto puedes recuperar los originales. ¿Laborioso? Tal vez, pero efectivo.
Reutilizar las claves para el OTP, aunque sólo sea una vez, anula la gran seguridad del sistema y lo hace bastante vulnerable a ataques. Quiero decir, se llama one-time pad; esta información no debería ser muy sorprendente. Pero tener una clave para cada mensaje es complicado y no está exento de riesgos. Por ello, aunque el OTP pueda ser interesante para según qué propósitos, y haya sido utilizado en el pasado en determinadas circunstancias, en la práctica lo más apropiado es usar otros métodos más recientes para poder enviar mensajes de forma segura. Lamento la decepción que esto te haya podido causar. Por otra parte, el que aún quede criptografía para rato nos permite seguir hablando de otros criptosistemas, que tienen su interés desde el punto de vista matemático. Y ¿no es por eso por lo que estás aquí, para aprender matemáticas? No hace falta que respondas.