La semana pasada, aprendimos la teoría numérica
necesaria para la criptografía de clave pública.
Esta semana vamos a poner a trabajar ese
conocimiento y vamos a construir varios
esquemas de criptografía de clave pública seguros.
Pero primero es necesario definir qué es
la criptografía de clave pública y qué significa
que la criptografía de clave pública sea
segura. Así, permitidme recordaros que en un
esquema de criptografía de clave pública hay un
algoritmo de encriptación, normalmente denotado
como E, y un algoritmo de
desencriptado que denotamos como D. En cualquier
caso, aquí el algoritmo de encriptación usa una
clave pública, mientras que el de desencriptado
usa una clave privada. Este par se denomina
par de claves. Y la clave pública se utiliza para
encriptar mensajes mientras que la clave privada
se utiliza para desencriptarlos. Por tanto, en este
caso, un mensaje "m" se encripta usando
la clave pública y lo que se obtiene de ello es el
texto cifrado, "c". Y, de forma similar,
el texto cifrado se usa para alimentar el algoritmo de
desencriptado usando la clave privada y lo que
se obtiene del algoritmo de desencriptado es
el mensaje original, "m". La encripción de clave
pública tiene muchas aplicaciones. La semana
pasada vimos la aplicación clásica, el
establecimiento de sesión, esto es, intercambio de
claves. Y por ahora vamos a limitarnos al intercambio de
claves que sea seguro sólo contra escucha. Y, si
recordáis cómo funciona el protocolo,
básicamente Alice, lo que ella hará es generar
un par de claves pública y privada.
Enviará la clave pública a Bob. Bob
generará un valor aleatorio "x", que
servirá como su secreto compartido y,
entonces, envía "x" encriptada a Alice,
encriptada con su clave pública [de Alice]. Alice puede
desencriptar, recuperar "x" y ahora ambos
disponen de este secreto compartido, "x", que
pueden utilizar para comunicarse de forma segura
entre ellos. El atacante, por supuesto, todo lo que
puede ver es la clave pública, la
encriptación de "x" con la clave pública, de la cual
no debería poder obtener ninguna
información sobre "x". Vamos a definir esto
de forma más precisa para entender
qué significa no ser capaz de averiguar nada
sobre "x". La criptografía pública,
de hecho, tiene muchas otras aplicaciones.
Por ejemplo, es muy útil en
aplicaciones no interactivas. Así, pensad en un
sistema de correo electrónico, por ejemplo. Aquí, Bob
quiere enviar correo a Alice y, cuando Bob
envía el correo, el correo pasa de
agente de transporte a agente de transporte hasta que
llega a Alice, momento en el que Alice deberá
desencrciptar. La forma en que el sistema de correo
está implementado está diseñada según una
configuración no interactiva en la que Bob envía
el correo y entonces Alice se supone que lo
recibirá. Y Alice no debería tener que comunicarse
con Bob a fin de desencriptar
el correo. Por tanto, en este caso, a causa de la
falta de interactividad, no existe la oportunidad
de establecer un secreto compartido entre Alice y
Bob. Por tanto, en este caso, lo que
ocurrirá es que Bob, básicamente, enviará
el correo encriptado utilizando la clave pública de
Alice. Del mismo modo que él envía el correo, cualquiera
en el mundo puede enviar el correo encriptado a
Alice, encriptado usando su clave pública [de Alice].
Cuando Alice recibe este correo, ella utiliza
su clave privada para desencriptar el texto cifrado y
recuperar el mensaje en texto llano.
Por supuesto, el inconveniente en un sistema como
éste es que, de hecho, Bob necesita, de algún modo,
obtener la clave pública de Alice. Así, por ahora, vamos
a asumir, simplemente, que Bob ya dispone
de la clave pública de Alice, pero más adelante,
cuando hablemos sobre firmas digitales,
veremos cómo se puede hacer esto de
forma muy eficiente utilizando lo que se
llama gestión de clave pública y, como ya he
dicho, volveremos a ello más adelante.
Lo más importante que quiero que recordéis es
que la criptografía de clave pública se
utiliza para establecer sesiones. Esto es muy
común en la web, donde la criptografía de
clave pública se utiliza para establecer una clave
segura entre un navegador web y un servidor web.
Y la criptografía de clave pública también es muy
útil para aplicaciones no interactivas,
en las que cualquiera en el mundo, de forma
no interactiva, necesita enviar un mensaje
a Alice, pudiendo encriptar el mensaje usando la
clave pública de Alice y Alice puede desencriptar
y recuperar el texto llano. Por tanto, permitidme que
os recuerde con algo más de detalle qué
es un sistema de criptografía de clave pública. Bien,
consiste en tres algoritmos, G, E y D.
G se denomina algoritmo de generación de
claves. Básicamente lo que hace es
generar este par de claves, la clave pública y la
clave privada. Tal como se indica aquí, G no usa
argumentos, pero en la vida real, G realmente usa
un argumento denominado el parámetro
de seguridad, que especifica el tamaño de las
claves que se generan con este algoritmo de
generación de claves. Luego está este algoritmo
de encriptación, como es habitual, que usa una
clave pública y un mensaje y genera un texto
cifrado, y un algoritmo de desencriptado que
usa la clave privada correspondiente y un
texto cifrado y genera el correspondiente
mensaje. Como siempre, para [la condición de]
consistencia, diremos que si encriptamos un mensaje
según una determinada clave pública y luego lo
desencriptamos con la clave privada correspondiente,
deberemos obtener de nuevo el mensaje original. Ahora,
¿qué significa para un sistema criptográfico de clave pública
que sea seguro? Voy a empezar definiendo
seguridad contra escucha
y luego definiremos la seguridad contra
ataques activos. La forma de
definir seguridad contra escucha es muy
similar a la del caso simétrico que hemos
visto la semana pasada, así que vamos a pasar
por ello rápidamente, sólo como repaso.
Básicamente, el juego de ataque se define como
sigue. Definimos estos dos experimentos,
experimento cero y experimento uno. En
cada experimento el retador generará
un par de claves pública y privada.
Le dará la clave pública
al adversario. El adversario emitirá
dos mensajes, m0 y m1 de la misma
longitud y lo que recibe es la
encripción de m0 o la
encripción de m1. En el experimento cero
obtiene la encripción de m0. En el experimento
uno obtiene la encripción de m1. Y entonces el
adversario se supone de debe indicar cuál
ha recibido, ¿Ha recibido la encripción de
m0 o ha recibido la encripción de m1? Así,
en este juego, el atacante sólo obtiene un
texto cifrado. Esto corresponde a un ataque
de escucha en el que se limita a "escuchar"
dicho texto cifrado "c". Y ahora
su objetivo es determinar si el texto cifrado "c"
es la encripción de m0 o m1. No se
permite manipular el texto cifrado "c" por ahora.
Y, como es costumbre, diremos que el
esquema de criptografía de clave pública es
semánticamente seguro si el atacante no puede
distinguir el experimento cero del experimento
uno. En otras palabras, no puede
diferenciar si recibió la encripción de m0
o la encripción de m1. Antes de pasar
a los ataques activos, quiero mencionar una
relación inmediata entre la definición que acabamos
de ver y la definición de seguridad de
escucha para cifrado simétrico.
Si lo recordáis, cuando hablamos sobre
seguridad de escucha para cifrado
simétrico, distinguíamos entre el caso en que la
clave se usaba una vez y el caso en que la
clave se usaba varias veces. Y, de hecho,
vimos que existe una clara
separación. Por ejemplo, el cuaderno de un solo
uso es seguro si la clave se usa para encriptar
un único mensaje, pero es completamente inseguro
si la clave se usa para encriptar múltiples
mensajes. Y, de hecho, teníamos dos definiciones
diferentes, si os acordáis, teníamos una
definición para seguridad de un solo uso y una
definición diferente, que era más
exigente, cuando la clave se usaba varias
veces. La definición que os he mostrado en
la transparencia anterior es muy similar a la
definición de seguridad de un solo uso para
cifras simétricas. Y, de hecho, resulta que para
la criptografía de clave pública, si un
sistema es seguro en el caso de un solo uso de la clave,
en cierto sentido, también es seguro para uso múltiple de
la clave. En otras palabras, no es necesario
proporcionar explícitamente al atacante la habilidad
para requerir encripciones de mensajes de su
elección, ya que puede crear encripciones
por si mismo. Dispone de la clave
pública y, por tanto, puede
por si mismo encriptar cualquier mensaje que desee.
Como resultado, cualquier par de claves pública y privada
de algún modo inherentemente se usan para
encriptar varios mensajes ya que el atacante
podría encriptar muchos, muchos mensajes
de su elección usando la clave
pública que le hemos proporcionado en el
primer paso. Y así, como resultado, de hecho
la definición de seguridad para un solo uso es
suficiente para implicar seguridad de varios usos y
es por ello que nos referimos al concepto como
indistinguibilidad bajo un ataque de
texto llano escogido. Así, este es sólo un punto menor
para explicar por qué en la configuración de criptografía
de clave pública no necesitamos una
definición más compleja para aprehender
la seguridad ante escucha. Ahora que
entendemos la seguridad ante escucha,
vamos a ver adversarios mas fuertes que pueden
montar ataques activos. Entonces, en
particular, veamos el ejemplo del correo electronico.
Así, aquí tenemos a nuestro amigo Bob
que quiere enviar enviar un correo a su amiga
Caroline. Y resulta que Caroline tiene una
cuenta en Gmail. Y esto funciona básicamente
así, el correo electrónico se envía encriptado al
servidor de Gmail. El servidor de Gmail desencripta
el correo electrónico, mira quienes son los
destinatarios y luego, si es que el
destinatario es Caroline,
reenvia el correo electrónico a Caroline.
Si el destinatario es el atacante, se
lo reenvia al atacante. Esto es similar a
cómo trabaja realmente Gmail,
porque el remitente enviaría el correo encriptado
sobre SSL al servidor Gmail,
el servidor Gmail terminaría [la sesión] SSL y
reenviaría el mensaje a los destinatarios
apropiados. Ahora supongamos que Bob
encripta el correo usando un sistema que
permita al adversario manipular el
texto cifrado sin ser detectado. Por
ejemplo, imaginad que el correo está
encriptado usando el modo contador o
similar. Entonces, cuando el atacante intercepta
este correo puede cambiar el destinatario
de forma que ahora el destinatario sea
attacker@gmail.com. Y sabemos que, para el
modo contador, por ejemplo. esto es muy
fácil de hacer. El atacante sabe que el
correo está dirigido a Caroline, él está sólo
interesado en el cuerpo del correo. Por tanto, puede
fácilmente cambiar el destinatario del correo
a attacker@gmail.com y ahora, cuando el servidor
recibe el correo, lo desencriptará, verá que
el destinatario se supone que es el
atacante y reenviará el cuerpo del mensaje al
atacante. Ahora el atacante ha podido
leer el cuerpo del mensaje que
estaba destinado a Caroline. Así,
este es un ejemplo clásico de ataque activo, y
podéis ver lo que el atacante ha conseguido:
puede desencriptar cualquier texto cifrado
en el que el destinatario sea "to:attacker",
esto es, un texto cifrado en el que el texto llano
empiece por "to:attacker". Así, nuestro objetivo es
empiece
diseñar sistemas de clave pública que sean
seguros incluso si el atacante puede manipular
el texto cifrado y, posiblemente, desencriptar
algunos textos cifrados. Y, de nuevo, quiero
enfatizar que aquí el objetivo del atacante es
obtener el cuerpo del mensaje. El atacante
ya sabía que el correo estaba destinado
a Caroline. Y todo lo que él tenía que hacer
era cambiar el destinatario. Así, este
ataque mediante manipulación motiva la
definición de seguridad de texto cifrado escogido.
y, de hecho, esta es la noción estándar de
seguridad para la criptografía de clave pública. Así,
permitidme explicaros cómo funciona el esquema del
ataque. Como ya dije, nuestro objetivo es construir
sistemas que sean seguros bajo esta noción tan
conservadora de encripción. Así, tenemos un
esquema de encripción G, E, D y digamos que
está definido sobre nuestro espacio de mensajes
y de textos cifrados M, C. Como es habitual, vamos
a definir dos experimentos, experimento cero y
experimento uno. Así, aquí "b" indica si
el retador está implementando el
experimento cero el el experimento
uno. El retador empieza generando una clave
pública y una clave privada y entonces proporciona
la clave privada al adversario. Ahora el adversario
puede decir "Bien, aquí hay un puñado de
textos cifrados, por favor desencríptalos por mí." Así
que el adversario envía el texto cifrado
c1 y obtiene la desencripción del
texto cifrado c1, esto es, m1. Y lo repite
una y otra vez, de forma que envía el
texto cifrado c2 y obtiene la desencripción,
que es m2, el texto cifrado c3 y lo obtiene
desencriptado, m3, y así en adelante.
Finalmente, el adversario dice: "Esta fase
de interrogación ha acabado" y ahora
remite básicamente dos mensajes de la misma
longitud, m0 y m1, como es habitual, y
recibe en respuesta el texto cifrado de
desafío, "c", que es la encriptación de m0 o
la encriptación de m1, dependiendo de si
estamos en el experimento cero o el
experimento uno. Ahora el adversario puede
continuar enviando solicitudes de texto
cifrado. Así, puede continuar remitiendo
solicitudes de desencriptado. Así, el remite
un texto cifrado y recibe el texto desencriptado,
pero, por supuesto, ahora tiene que haver una
limitación. Si el atacante pudiese solicitar textos
cifrados arbitrarios de su elección,
por supuesto que podría romper el desafío. Lo
único que tendría que hacer es remitir al
retador el texto cifrado "c" como una solicitud de
desencriptado y entonces se le diría si en la
fase de desafío se le ha dado la encriptación
de m0 o la encriptación de m1.
Como resultado, ponemos la siguiente limitación,
que dice que él puede de hecho enviar cualquier
texto cifrado de su elección, excepto el texto
cifrado del desafío. Así, el atacante
podrá solicitar el desencriptado de cualquier
texto cifrado de su elección que no sea el
texto cifrado del desafío. Y, a pesar de que se le hayan
dado todos esos textos desencriptados, a pesar de todo
no debería ser capaz de decir si ha
recibido la encriptación de m0 o la
encriptación de m1. Por tanto, daros cuenta de que
se trata de una definición muy conservadora. Proporciona
al atacante más poder del que vimos en la
transparencia anterior. En la transparencia anterior,
el atacante sólo podía desencriptar mensajes
si el texto llano empezada con "to:attacker".
Aquí, lo que vemos es que el atacante puede
desencriptar cualquier texto cifrado de su elección,
siempre se que sea distinto del texto cifrado del
desafío, "c". ¿De acuerdo? Y entonces su
objetivo es decir si el texto cifrado del
desafío es la encriptación de m0 o la
encriptación de m1. Y, como es habitual, si no
puede hacerlo, en otras palabras, su respuesta
ante el experimento cero es básicamente la
misma respuesta que en el experimento
uno, sin ser capaz de diferenciar la
encriptación de m0 de la encriptación de
m1 a pesar del poder del que disponía,
entonces decimos que el sistema es semánticamente
seguro frente a ataque de texto cifrado escogido,
seguro CCA. En ocasiones se utiliza este acrónimo,
el acrónimo de INDistinguible frente a un Ataque
de texto Cifrado esCogido [IND-CCA], pero me voy
a limitar a llamarlo "seguro CCA". Así, vamos a ver
como esto refleja el ejemplo con el correo electrónico
que vimos antes. Supongamos que el sistema de
encriptación usado es tal que simplemente dada
un mensaje encriptado el atacante puede
cambiar el destinatario, digamos, de Alice
a Charlie. Entonces, así es como él
ganaría el juego CCA. Bien, en el
primer paso recibe, por supuesto, la clave
pública. Y entonces el atacante lo que hará
es proporcionar dos mensajes de igual longitud,
esto es, en el primer mensaje el cuerpo contendrá
un cero. En el segundo mensaje el cuerpo contendrá
un uno. Pero ambos mensajes están dirigidos a
Alice. Y, en respuesta, él recibirá el
texto cifrado del desafío, "c".
Bien, así que ahora tenemos nuestro texto
cifrado del desafío, "c". Ahora, lo que hará el
atacante es utilizar su habilidad para
modificar el destinatario.
Y devolverá un texto cifrado c' [c prima]
en el que c' es la encriptación del
mensaje para Charlie con el cuerpo del
desafío, "b". Esto es, si os acordáis, o
cero o uno. Ahora, como que el
texto llano es diferente, sabemos que
el texto cifrado debe también ser diferente.
En particular, c' debe ser diferente del
texto del desafío "c", ¿no es así? Esto es,
c' debe ser diferente de "c". Y como
consecuencia, el pobre retador ahora tiene
que desencriptar, por definición del juego CCA.
El retador tiene que desencriptar cualquier texto
crifrado que no sea igual a un texto cifrado enviado
por el retador. Así, el retador desencripta, le
da al adversario m'. Básicamente proporciona
al adversario "b". Y ahora el adversario
puede mostrar "b" como resultado del desafío
y gana el juego con ventaja 1. Así, su
ventaja con este esquema particular
era uno. Simplemente porque el atacante
era capaz de cambiar el texto cifrado del
retador de un destinatario a otro, lo
que le permite ganar el juego CCA con
ventaja uno. Así, como ya dije, [el modelo] de
seguridad de texto cifrado escogido es en
realidad la noción de seguridad correcta para los
sistemas de criptografía de clave pública. Y este es
un concepto muy interesante. De algún modo,
aunque el atacante tenga la habilidad para
desencriptar todo lo que quiera, excepto el
texto cifrado del desafío, no es capaz de
conocer el texto cifrado del retador. Así, lo que haremos
lo que haremos durante lo que queda de este módulo y,
de hecho, también el próximo, es construir
sistemas seguros CCA. Se tiene que
destacar que es posible y voy a
mostraros exactamente cómo
hacerlo. Y, de hecho, los sistemas
seguros CCA que construiremos
son los que se utilizan en el mundo real.
Y cada vez que se ha intentado implementar un
sistema de criptografía de clave pública que no ha
sido seguro CCA, alguien ha encontrado un
ataque y ha sido capaz de romperlo. Y vamos
a ver algunos ejemplos de esos ataques
en unos pocos segmentos.