Quantcast
Channel: El blog de García Larragan y Cía
Viewing all 638 articles
Browse latest View live

Criptografía (XXXVIII): ataque a RSA mediante cifrado cíclico

$
0
0
En un post anterior sobre el algoritmo RSA comentaba que se considera que éste será seguro hasta que no se conozca una forma eficiente de hallar los dos factores primos de un número muy grande resultado del producto de éstos, ya que con los ordenadores actuales la potencia de cálculo que se requiere para ello hace que esta tarea sea inabordable en un tiempo razonable.

Pero, ¿existen otros métodos para intentar "romper" el cifrado RSA sin necesidad de realizar esa factorización?. Además, ¿podría "romperse" este cifrado sin conocerse la clave privada del receptor del mensaje?. La respuesta a ambas preguntas es afirmativa, al meno, en teoría.

Pongo un ejemplo de ataque a un cifrado RSA utilizando el método de cifrado cíclico.

En el ejemplo de cifrado RSA que puse en el post anterior al que he hecho referencia realizaba una operación de cifrado y descifrado sobre un mensaje (m) considerando lo siguiente:

Clave pública del receptor (7, 52.841)
Clave privada del receptor (7.399, 52.841)
m = 17.225

Cifrado (el emisor utiliza la clave pública del receptor): c = me mod n = 17.2257 mod 52.841 = 1.855
Descifrado (el receptor utiliza su clave privada): m = cd mod n = 1.8557.399 mod 52.841 = 17.225

Supongamos ahora que interceptamos este mensaje cifrado o criptograma (1.855): ¿podríamos obtener el mensaje en claro a partir de éste y de la clave pública del receptor?. Pues, también en teoría, sí.

El ataque empleando el cifrado cíclico consiste en cifrar repetidas veces el criptograma interceptado con la clave pública del destinatario hasta volver a obtener el criptograma, cosa que tarde o temprano ocurrirá y que nos revelará el mensaje en claro, de la siguiente manera:
Es decir, la operación de cifrado anterior a aquella en la que se obtiene nuevamente el criptograma (c) nos revela el mensaje en claro (m).

Curioso, ¿no?. Nótese que con este método no se obtiene la clave privada del receptor, pero se "rompe" el secreto que se pretendía guardar (el mensaje en claro). Lástima que este método con la potencia de cálculo disponible actualmente resulte incluso más ineficiente que el de la factorización cuando se utilizan números lo suficientemente grandes para generar las claves :). 

Zorionak eta urte berri on 2017!

$
0
0
Como siempre, llegadas estas fechas, no puedo dejar (¡hombre!, por poder si podría, pero no me da gana :) ) de desearos:

¡Lo mejor para este año que termina, para el siguiente y para siempre!.

Como tampoco podía ser de otra forma, este año he escrito muchas entradas en este blog sobre criptografía, en la felicitación se encuentra mi nombre cifrado ;).

Gimnasia mental (XXVIII): probabilidad de que me toque el Gordo de Navidad

$
0
0
El otro día, tras mi jornada laboral y como casi siempre, entro en mi bar de referencia en Algorta (Getxo), el pueblo más bonito del mundo :).

En él me encuentro con un ilustre parroquiano que me interroga inmediatamente, antes de pedir ninguna consumición: Mikel,

¿Qué probabilidad hay de que te toque el Gordo de Navidad?.

Por la cara que puso, me miraba fijamente y arqueando una ceja, enseguida pensé que la pregunta podía tener trampa y, además, sospeché que no me iba a poder escaquear de responder; me había visto comprar un décimo en ese mismo bar el día anterior, por lo que alguna probabilidad tendré y, peor aún y como digo, él lo sabía (no podía contestar eso de: "Ninguna, porque no juego").

Tras unos segundos meditando, acordándome de un tal Laplace, le contesté que como yo sólo he comprado un décimo de un número, como creo que hay 100.000 números (del 0 al 99.999) y que pienso que todos ellos tienen la misma probabilidad de salir premiados con el Gordo, entonces la probabilidad de que a mí me toque el Gordo de Navidad es de 1/100.000 = 0,00001 (casos favorables/casos posibles, es decir, un ridículo 0,001%).

En ese momento, su expresión inquisidora se tornó en una de absoluta satisfacción (¡otro que no tiene ni idea!. Vaya usted a saber a cuantos les había hecho esa misma pregunta), y me dijo: "En el sorteo de Navidad hay dos bombos, el primero de ellos con los 100.000 números posibles y el segundo con el premio que le corresponde al número que sale en el primero, por lo que la probabilidad de que que te toque el Gordo es mucho menor que el 0,001%" (supongo que con ese argumento se refería a probabilidad condicionada, pero vaya usted a saber).

¿Quién crees que tiene razón?.

Criptografía (XXXIX): RSA o por qué los números aleatorios son demasiado importantes para dejarlos en manos del azar

$
0
0
Decía en el primer post sobre RSA que utilizando este algoritmo el emisor cifra el mensaje con la clave pública del receptor y que el criptograma resultante sólo puede descifrarse utilizando la clave privada de este último. Esto es una de las primeras cosas que uno aprende al estudiar cómo funciona el cifrado y descifrado usando este algoritmo, pero: ¿es cierto?.

Prescindiendo del ataque a RSA mediante cifrado cíclico, que, como vimos en este post, en teoría nos permitiría descifrar un mensaje concreto cifrándolo sucesivas veces con la clave pública del destinatario hasta volver a obtener el criptograma: ¿sería posible descifrar el criptograma utilizando una clave distinta de la clave privada correspondiente a la clave pública con la que se cifró?. Pues he aprendido que sí, aunque esto parezca ir en contra de la seguridad de este algoritmo.

Veamos un ejemplo:

En el primer post al que he hecho referencia realicé el cifrado de un mensaje (m) con una clave pública (e, n) y su posterior descifrado con la clave privada correspondiente (d, n), de la siguiente manera:

m = 17.225

Clave pública (e, n): (7, 52.841) 
Cifrado: c = me mod n = 17.2257 mod 52.841 = 1.855

Clave privada (d, n): (7.399, 52.841)
Descifrado: m = cd mod n = 1.8557.399 mod 52.841 = 17.225

Vamos ahora a utilizar otras 3 claves diferentes a la clave privada en el cuerpo de cifra (n) para intentar descifrar el criptograma (c):

k1: (20.347, 52.841)
Descifrado: m = 1.85520.347 mod 52.841 = 17.225

k2: (33.295, 52.841) 
m = 1.85533.295 mod 52.841 = 17.225

k3: (46.243, 52.841) 
m = 1.85546.243 mod 52.841 = 17.225

Como se observa, en los tres casos conseguimos descifrar el criptograma sin utilizar la clave privada del destinatario.

- ¿Por qué ocurre esto?. Hay que tener en cuenta que, tal y como comentaba en el primer post, al generarse un par de claves, la clave privada se calcula como el inverso del exponente de la clave pública (e) en el cuerpo j(n) = (p - 1)(q - 1), siendo 'p' y 'q' los dos números primos aleatorios a partir de los cuales se genera el par de claves, y 'n' su producto. Como 'e' y j(n) son coprimos o primos relativos, es decir, mcd(e, j(n)) = 1, esto asegura que el exponente de la clave privada (d) existe, es decir, que 'e' tiene inverso módulo j(n) y, además, que éste (d) es el único inverso de 'e' en el cuerpo j(n).

Lo que ocurre es que como el cuerpo de cifra no es j(n) sino 'n' existirá al menos otro inverso de 'e' en el cuerpo de cifra 'n' con el que también se podrán descifrar los mensajes cifrados con la clave pública (e, n).

- ¿Puedo saber cuántas claves de este tipo existen al generar un par de claves?. Esto depende de los dos números primos aleatorios ('p' y 'q') empleados para generar el par de claves, y puede calcularse de la siguiente forma:
En nuestro caso:
- ¿Puedo saber cuáles son estas claves al generar un par de ellas?:

Calculamos: d1 = inv(e, mcm(p-1, q-1)

Los exponentes de estas claves, incluido el de la clave privada (d), serán:

di = d1 + (i-1) x mcm(p-1, q-1)

Donde: 1 < di< n

Por lo que las claves, incluida la clave privada, serán:

ki: (di, n)

En nuestro caso:

d1 = inv(7, mcm(52, 996)) = inv(7, 12.984) = 7.399

Por lo que los exponentes de estas claves. incluido el de la clave privada (d), serán:

d1 = d1 + (i-1) x mcm(p-1, q-1) = 7.399 + 0 x 12.948= 7.399
d2 = d1 + (i-1) x mcm(p-1, q-1) = 7.399 + 1 x 12.948 = 20.347
d3 = d1 + (i-1) x mcm(p-1, q-1) = 7.399 + 2 x 12.948 = 33.295
d4 = d1 + (i-1) x mcm(p-1, q-1) = 7.399 + 3 x 12.948 = 46.243

Por tanto, incluida la clave privada, las claves serán:

k1: (7.399, 52.841)
k2: (20.347, 52.841)
k3: (33.295, 52.841)
k4: (46.243, 52.841)

Es decir, además de la clave privada (7.399, 52.841), existen otras tres claves con las que se pueden descifrar los criptogramas cifrados con la clave pública (7, 52.841).

- ¿Al generarse un par de claves podrían existir muchas claves de este tipo que hagan vulnerables los criptogramas a una ataque de fuerza bruta?. Pues, en teoría, sí. Ya he dicho que el número de ellas depende de los número primos aleatorios que se empleen para generarlas.

Veamos que ocurre variando los números primos empleados para generar el par de claves de nuestro ejemplo, que eran p = 53 y q = 997 (en este caso, eligiendo '7' como exponente de la clave pública existen 3 claves de este tipo. En los casos que se indican a continuación también elegimos '7' como exponente de la clave pública):

1.- p = 53; q = 53

n = 2.809; clave pública: (7, 2.809); clave privada: (1.159, 2.809)

Aplicando las fórmulas indicadas anteriormente, calculamos que existen 53 claves de este tipo. La primera (15, 2.809), y todas ellas, cuyos exponentes se encuentran separados a lo largo del cuerpo de cifra por 52 (mcm(p-1, q-1)), serán: (15, 2.809), (67, 2.809), (119, 2.809), (171,2.809), (223,2.809),...   

2.- p = 997; q = 997

n = 994.009; clave pública: (7, 994.009); clave privada: (708.583, 994.009)

Existen 997 claves de este tipo: (427, 994.009), (1.423, 994.009), (2.419, 994.009),...

3.- p = 53 ; q = 1.171

n = 62.063; clave pública: (7, 62.063); clave privada: (17.383, 62.063)

Existen 26 claves de este tipo: (1.003, 62.063), (3.343, 62.063), (5.683, 62.063),...

4.- p = 53; q = 983

n = 52.099; clave pública: (7, 52.099); clave privada: (7.295, 52.099)

Existe sólo 1 clave de este tipo: (32.827, 52.099).

Como se ve, al menos yo, saco inicialmente las siguientes conclusiones:

1.- No parece una buena idea utilizar el mismo número primo para 'p' y 'q'.

2.- El número de claves de este tipo, tal y como comentaba, tiene una fuerte dependencia directa de la elección de los dos números primos aleatorios a partir de los cuales se genera el par de claves

- ¿Cómo puede evitarse que al generar un par de claves existan muchas claves de este tipo?.

Parece ser, por lo que voy aprendiendo, que utilizando números primos fuertes o primos seguros en la generación del par de claves. Pero esto es algo que tengo que estudiar e intentar comprender antes de contarlo :). Si lo consigo escribiré otra entrada para compartirlo.

Por tanto, entiendo que es muy importante que los números primos 'p' y 'q' a partir de los cuales se genera el par de claves no sean predecibles, ya que en ellos descansa el secreto de las comunicaciones entre el emisor y el receptor, y la idea de seleccionarlos de forma aleatoria parece la mejor opciónNo obstante, visto lo visto y por otros efectos no deseados que podrían producirse si se realiza una elección no adecuada de los mismos, la frase que oí en su día y que me hizo mucha gracia empieza a tener sentido para mí:

"Los números aleatorios son demasiado importantes para dejarlos en manos del azar"

Gimnasia mental (XXIX): probabilidad de que me toque el Gordo del Niño

$
0
0
Como complemento a este post, en el que me preguntaba: ¿Cuál es la probabilidad de que me toque el Gordo de Navidad?, en éste me pregunto:


"¿Qué probabilidad hay de que me toque el Gordo de la lotería del Niño: mayor, menor o igual que en la lotería de Navidad?".

Si no estoy equivocado, según tengo entendido (por favor, si no es así que alguien me corrija):

- En la lotería de Navidad hay un bombo con 100.000 bolas con los números (del 0 al 99.999) y en otro están las bolas con los premios; de tal forma que se van extrayendo del primero las bolas con los números agraciados y del segundo las bolas con el premio que corresponde a cada uno de los anteriores.

- En la lotería de Niño se utiliza el sistema de bombos múltiples, es decir, hay cinco bombos con 10 bolas cada uno (del 0 al 9), una para cada uno de los cinco dígitos posibles (decena de millar, unidad de millar, centena, decena y unidad, respectivamente) que podrían formar los 100.000 números posibles (del 0 al 99.999); de manera que tras la extracción de una bola de cada uno de los cinco bombos se obtiene el número agraciado con el premio programado (los premios van saliendo de forma ordenada ascendente por cuantía) y después se reponen las bolas extraídas en sus respectivos bombos.

También, tal y como tengo entendido, en el sorteo de Navidad resultan premiados menos números que en el del Niño.

La pregunta en concreto es, suponiendo que juego un único décimo en cada sorteo:

¿Qué probabilidad existe de que me toque el Gordo en cada uno de ambos sorteos?:

a) Mayor en la Lotería de Navidad que en la del Niño.
b) Mayor en la del Niño que en la de Navidad.
c) La misma en ambos sorteos.

Criptografía (XL): ataque a RSA mediante la paradoja del cumpleaños

$
0
0
Decía en un post anterior de esta serie que existen algunos métodos para intentar "romper" el cifrado RSA sin necesidad de factorizar el módulo para hallar sus dos factores primos.

Como comenté en ese post, el ataque utilizando el cifrado cíclico nos podría permitir "romper" el secreto que se pretende guardar (en teoría se puede obtener el mensaje en claro), aunque no obtendríamos la clave privada del receptor.

Pero, ¿existen otros métodos de criptoanálisis al cifrado RSA que teniendo en cuenta sólo información pública del destinatario (la clave pública con la que se cifran los mensajes en claro: el exponente y el módulo) podrían revelarnos su clave privada?. La respuesta es, otra vez y en teoría, sí, y, además, ni siquiera haría falta interceptar un criptograma, como sí que es necesario en el caso del ataque mediante cifrado cíclico. Éste es el caso de un ataque basado en la paradoja del cumpleaños.

Veamos un ataque de este tipo con el ejemplo que vengo utilizando en esta serie de posts:

Clave pública del receptor (e, n): (7, 52.841)
Clave privada del receptor (d, n): (7.399, 52.841)
mensaje (m) = 17.225

Cifrado (el emisor utiliza la clave pública del receptor): c = me mod n = 17.2257 mod 52.841 = 1.855.
Descifrado (el receptor utiliza su clave privada): m = cd mod n = 1.8557.399 mod 52.841 = 17.225.


Tal y como he comentado, para realizar el ataque partimos únicamente de la clave pública del receptor (e, n), que como su propio nombre indica es información pública.

Conocido el módulo 'n' (52.841) dividimos el espacio del cuerpo de cifra en dos mitades, de la siguiente manera:
Escogemos un número cualquiera (m). Por ejemplo: 4.683.

Y ahora vamos realizando simultáneamente las dos siguientes operaciones:


ci= mi mod n
cj = mj mod n

hasta encontrar una colisión, es decir, que uno de los valores obtenidos en la primera mitad del espacio del cuerpo de cifra coincida con uno de los obtenidos en la segunda mitad, o viceversa. Si esto ocurre el ataque puede haber prosperado de forma que a partir de los valores de i y j sea posible obtener la clave privada del destinatario (d, n) o una clave que siendo diferente a ésta nos permita descifrar los criptogramas (ver este post).

En nuestro ejemplo:
Como se observa, para i = 524 y j = 26.420 se produce una colisión, por lo que el ataque podría haber prosperado en tan sólo 524 iteraciones (2 cifrados en cada una de ellas) en un cuerpo de cifra aproximadamente 100 veces mayor. Comprobémoslo:

- Calculamos: x = |i - j| / mcd(e, |i - j|) = |524 - 26.420| / mcd(7, |524 - 26.420|) = 25.896 / mcd(7, 25.896) = 25.896.

- El exponente de la clave podría ser: inv(e, x) = inv(7, 25.896) = 7.399, y, tal y como se puede ver al inicio de este ejemplo, efectivamente hemos obtenido el exponente (d) de la clave privada del receptor, por lo que esta última es (7.399, 52.841).

¿Hemos tenido mucha suerte?. Parece que sí, ya que a simple vista no parece muy probable que se produzca una colisión en la iteración 524 en un cuerpo de cifra aproximadamente 100 veces mayor. Sin embargo, conforme a la paradoja del cumpleaños (ver este post donde la explico), creo que en nuestro ejemplo sólo harían falta 195 iteraciones (2 cifrados en cada una de ellas) para que la probabilidad de que se produzca una colisión sea superior al 50%.

De nuevo, como en el caso de ataque mediante cifrado cíclico (ver este post), aunque en teoría es posible, este tipo de ataque se convierte en una tarea inabordable en un tiempo razonable, por mucha potencia de cálculo de la que se disponga con los ordenadores actuales, cuando se utilizan números lo suficientemente grandes para generar las claves

Criptografía (XLI): ataque a RSA mediante módulo común

$
0
0
En anteriores posts de esta serie he hablado de algunos ataques teóricamente posibles al algoritmo de cifrado RSA (cifrado cíclico y paradoja del cumpleaños), pero que tal y como comenté son ineficientes cuando se utilizan números primos lo suficientemente grandes para generar el par de claves (pública y privada).

Además de los ya mencionados existen otros ataques posibles; y en este post trataré sobre uno de ellos: el ataque a RSA mediante módulo común.

La idea de este ataque consiste en explotar el hecho de que se utilice el mismo módulo (n) a la hora de generar pares de claves para diferentes usuarios (cada uno de ellos con su exponente publico y privado propios). En principio, esto no compromete la seguridad del algoritmo, pero deja la "puerta abierta" a que si se cifra el mismo mensaje para más de un usuario un criptoanalista que intercepte los criptogramas pueda hacerse con el mensaje en claro.

Veamos un ejemplo:

1.- Módulo común a los usuarios (n):  52.841.

2.- Clave pública de dos usuarios a los que se envía el mismo mensaje:

- Usuario 1 (e1, n): (11, 52.841).
- Usuario 2 (e2, n): (7, 52.841).

3.- Mensaje común a ambos usuarios (m): 16.708.

4.- Cifrado para cada uno de los dos destinatarios:

- El emisor utiliza la clave pública del Usuario 1: c1 = me1 mod n = 16.70811 mod 52.841 = 7.860.
- El emisor utiliza la clave pública del Usuario 2: c2 = me2 mod n = 16.7087 mod 52.841 = 52.061.

Supongamos ahora que se interceptan estos dos criptogramas y el criptoanalista sabe que el mensaje en claro es el mismo en ambos casos. Lo único que debe hacer para obtenerlo, ya que conoce e1e2, n, c1 y c2, es lo siguiente:

1.- Como e1 y e2 son primos entre sí (lo que ocurre en nuestro caso y es muy probable que en cualquier otro), existirán dos enteros (s, t) tales que:

e1 s + e2 t = mcd(e1e2) = 1

2.- Se calculan s y t mediante el algoritmo de Euclides extendido, de la siguiente forma:

a) r0 = e1 = 11; r1 = e2 = 7; s0 = 1; t0 = 0; s1 = 0; t1 = 1

b) i = 1

c) Mientras ri distinto de 0:

c.1) Dividir ri-1 entre ri para obtener el cociente qi+1 y el resto ri+1
c.2) si+1 = si-1 - qi+1 si; ti+1 = ti-1 - qi+1 ti
c.3) i = i + 1

d) Cuando ri = 0, el resultado buscado es ri-1 = r0 si-1 + r1 ti-1.

En nuestro caso:
3.- Y, finalmente, el criptoanalista obtiene el mensaje en claro realizando la siguiente operación (nótese que alguno de los dos valores obtenidos será necesariamente negativo. En nuestro caso: s = 2 y t = -3):

m = (c1s x inv(c2n)-t) mod n
m = (7.8602 x 23.1013) mod 52.841 = 16.708, que efectivamente, tal y como se puede comprobar más arriba, es el mensaje en claro.

Sin embargo, este tipo de ataque no es muy viable en la práctica a nada que se adopten unas mínimas precauciones en el uso de este algoritmo, ya que requiere que se intercepten criptogramas correspondientes a mensajes en claro idénticos para usuarios diferentes que compartan el mismo módulo, por lo que, por lo visto en éste y anteriores posts, y aunque hay otros tipos de ataques posibles, tras casi cuatro décadas desde su desarrollo, RSA parece gozar de una "salud" envidiable; a prueba de ruptura, salvo que alguien consiga dar con un algoritmo eficiente para hallar los dos factores primos de un número lo suficientemente grande, un incremento muy significativo de la potencia de cálculo de los ordenadores actuales y/o los avances que se logren en la computación cuántica, pero todo esto será, si es el caso, objeto de posts posteriores.

Criptografía (XLII): ataque a RSA mediante factorización (I)

$
0
0
Ya he dicho en posts anteriores que la fortaleza del cifrado RSA reside en el elevadísimo coste computacional al que tendrían que enfrentarse quienes pretendan atacar este algoritmo; y referido al caso concreto de la factorización del módulo (n) para hallar sus dos factores primos (p y q), en la enorme cantidad de cálculos a realizar para ello cuando se trata de números lo suficientemente grandes (actualmente se emplea para el módulo un tamaño de 2.048 bits).

Por tanto, se trata de un problema perfectamente resoluble desde un punto de vista matemático, pero inabordable actualmente por la ingente cantidad de tiempo y recursos necesarios.

Comienzo con este post un pequeño repaso a algunos de los métodos de factorización más conocidos para hacernos una idea del esfuerzo que esto conlleva. Para ello, intentaré factorizar mediante estos métodos el módulo del ejemplo que vengo utilizando en esta serie de posts (n = pq = 53 x 997 = 52.841).

- Método de factorización de Fermat:
En nuestro caso:
Aún con un número tan pequeño como módulo nos ha costado realizar 296 iteraciones para conseguir obtener sus dos factores primos, lo que puede parecer que no es mucho, pero este proceso presenta un carácter exponencial en función del tamaño de la entrada (el número a factorizar).

Sin embargo, cabe indicar que este método es muy eficiente cuando los dos factores están cercanos entre sí, o, lo que es lo mismo, cuando están próximos a la raíz cuadrada de n, ya que la factorización se resuelve en muy pocos pasos. Comprobémoslo con el siguiente ejemplo:
Como se observa los dos factores son números primos consecutivos y su factorización mediante este método se resuelve en un único paso, razón por la que es muy recomendable que en RSA los números primos aleatorios (p y q) elegidos como factores del módulo (n) se encuentren separado entre sí una cierta distancia. Ya decía yo en este post que "los números aleatorios son demasiado importantes para dejarlos en manos de azar" :).

No obstante, teniendo en cuenta esto último, que p y q se encuentren separados entre sí una cierta distancia, este método no es eficiente para factorizar el módulo en sus dos factores primos en un tiempo razonable cuando se trata de números lo suficientemente grandes, como digo actualmente se emplean números de 2.048 bits para el módulo (n).

Enposteriores postscontinuaré con el repaso de otros métodos de factorización, pero ya adelanto que: aunque hay algunos más eficientes que otros ante determinadas circunstancias, se van produciendo mejoras a los ya existentes y van surgiendo otros nuevos, de momento no existe un algoritmo que resuelva esta factorización en tiempo polinomial; lo que constituye el "Santo Grial" de los criptoanalistas para conseguir "romper" el cifrado basado en el algoritmo RSA.

Criptografía (XLIII): ataque a RSA mediante factorización (II)

$
0
0
Continúo con el pequeño repaso a algunos de los métodos de factorización más conocidos que inicié en el post anterior y que, en teoría, podrían emplearse para atacar al algoritmo de cifrado RSA.

Digo en teoría porque, como ya he venido insistiendo en esta serie de post, los métodos conocidos y que es posible implementar hasta la fecha no resuelven la factorización del módulo (n) en sus dos factores primos (p y q) en tiempo polinomial y, por tanto, son ineficientes para abordar este problema en un tiempo razonable cuando se trata de números lo suficientemente grandes (ya dije en el post anterior que actualmente se emplea un tamaño para el módulo de 2.048 bits).

En esta ocasión le toca el turno al método de factorización rho de Pollard.

Como siempre utilizaré el ejemplo que vengo usando en esta serie de posts (n = pq = 53 x 997 = 52.841).
En nuestro caso:
Como vemos, en tan sólo 6 iteraciones hemos conseguido factorizar el módulo (52.841) en sus dos factores primos (53 y 997); de forma significativamente más eficiente, en este caso, que con el método de Fermat al que me referí en el post anterior, pero, por lo que voy aprendiendo, no se puede afirmar rotundamente que un método sea más eficiente que otro, sino que esto depende del número concreto a factorizar.

Me pregunto: ¿cuál de estos dos métodos sería más eficiente en el ejemplo que puse en el post anterioren el que los dos factores primos estaban muy cercanos entre sí (n = pq = 991 x 997 = 988.027)?. Asunto que dejo como ejercicio para quien quiera resolverlo (como siempre se admiten conclusiones, etc. en forma de comentario a esta entrada).

En cualquier caso, comentar que se considera que el método de factorización rho de Pollard es eficiente para factorizar números compuestos con factores menores de 1012, lo que está muy por debajo de los utilizados actualmente por RSA.

En posteriores posts continuaré con este pequeño repaso a los métodos de factorización más conocidos.

Criptografía (XLIV): ataque a RSA mediante factorización (III)

$
0
0
En este post continúo con el pequeño repaso a los métodos de factorización más conocidos: en esta ocasión me referiré al método p - 1 de Pollard.

Al igual que los otros dos métodos de los que he hablado en posts anteriores (Fermat y rho de Pollard), se trata también de un método de factorización de propósito específico, es decir, el tiempo necesario para descomponer el módulo (n) en sus dos factores primos (p y q) depende de las características de estos últimos, en contraposición con los métodos de factorización de propósito general, en el que el tiempo de ejecución depende únicamente del tamaño del módulo.

Por lo que he entendido, el algoritmo podría ser el siguiente (como siempre, si estoy equivocado agradecería las oportunas correcciones a modo de comentario en esta entrada).
En nuestro caso (con el ejemplo que vengo utilizando en esta serie de posts):
En posteriores posts continuaré con este pequeño repaso a los métodos de factorización más conocidos.

Criptografía (XLV): ¿Sabías que...? (IX)

$
0
0
Quizá la aplicación práctica más "palpable" de los números primos se dé actualmente en la criptografía, ya que en ellos descansa en gran medida el secreto de nuestras más preciadas comunicaciones en Internet.

Así, los números primos son la base del algoritmo RSA, posiblemente el criptosistema de clave pública más utilizado en la actualidad, en el cuál el par de claves (pública y privada) correspondiente a cada usuario se calcula a partir de dos números primos aleatorios lo suficientemente grandes.

La fortaleza de este algoritmo reside en el elevado coste computacional de hallar los dos factores primos de un número lo suficientemente grande resultado del producto de ambos, aunque este último sea público y, por tanto, pueda ser conocido por cualquiera, ya que esta tarea no es factible en un tiempo razonable con los algoritmos de factorización conocidos que se pueden implementar hasta la fecha y con la potencia de cálculo de los ordenadores actuales, por mucha de esta última de la que se disponga. Por tanto, esos números primos son fundamentales para salvaguardar la confidencialidad de nuestras comunicaciones en Internet y deben mantenerse en secreto, ya que su conocimiento por parte de terceras personas haría inútil cualquier esfuerzo al respecto.

Sin embargo, pese a esa "palpable" aplicación práctica en la criptografía que comentaba al principio, ni siquiera somos conscientes de que utilizamos todo esto en nuestra vida cotidiana en nuestras relaciones por Internet con las administraciones públicas, entidades bancarias, etc.

Ya he escrito en este blog diferentes entradas sobre el algoritmo RSA (ver primer post) y aquí me centraré en los aspectos básicos de los números primos que a mí me parecen más curiosos y de éstos aplicados a la criptografía.

Dicho ésto, a todos nos enseñaron en el colegio que los números primos son aquellos números naturales mayores que 1 que únicamente son divisibles por sí mismos y por la unidad, y que los números compuestos, en contraposición a éstos, son aquellos números naturales que tienen otro u otros divisores diferentes además de sí mismos y de 1, pero, al menos que yo recuerde, sin darnos mayores explicaciones ni de su historia, ni de para qué sirven.

1.- ¿Es el 1 un número primo o compuesto?:

Pues parece ser que ni una cosa ni otra, pero sólo por convención y de forma relativamente reciente, es decir y en mi opinión, porque "estorba que sea una cosa u otra" :), ya que si fuera primo o compuesto habría que volver a formular importantes teoremas dando explicaciones adicionales.

2.- ¿Desde cuando se conoce la existencia de los números primos?:

No se sabe con certeza, ya que hay quien afirma que este conocimiento podría remontarse bastantes miles de años atrás, pero sí se puede datar con seguridad, como mínimo, alrededor del año 300 a.C.

Así, Euclides define en esa época los números primos y, poco más tarde, Eratóstenes idea un método para hallar todos los números primos menores o iguales que un número dado.

Por tanto, al menos, hace ya más de 2.000 años que los matemáticos vienen estudiando los números primos. Quizá les fascinaron porque, tal y como se dice, son los "átomos" de los que están constituidos todos los números naturales, es decir, cualquier número natural se puede descomponer en un producto de factores primos.

La criba de Eratóstenes para hallar todos los números primos menores o iguales que uno dado consistía en lo siguiente:

1.- Se escriben en forma de tabla todos los números naturales hasta aquel del que queremos hallar todos los números primos menores o iguales que él, incluido este último.

2.- Se tacha el 1, porque como ya he dicho no es un número primo.

3.- Se va hasta el siguiente número no tachado y, si el cuadrado de éste no es mayor que el número del que queremos hallar todos los números primos menores o iguales que él, este número es declarado como primo y se tachan todos los números de la tabla que sean múltiplo de él, y se vuelve a repetir este paso 3.

4.- Cuando el cuadrado del siguiente número no tachado sea mayor que el número del que queremos hallar todos los números primos menores o iguales que él, se declaran como primos todos los números no tachados de la tabla.

Ejemplo: supongamos que queremos obtener todos los números primos menores o iguales a 100. Gráficamente:
Creo que el algoritmo podría ser, más o menos, el siguiente:
En nuestro caso:
3.- ¿Cuántos números primos hay?:

Euclides fue el primero en formular una demostración sobre la infinitud de los números primos: "El conjunto formado por los números primos es infinito".

4.- ¿Es "fácil" determinar si un número dado es primo o compuesto?:

A la condición de que un número sea primo se le denomina primalidad y, por tanto, a la cuestión de determinar si un número dado es primo o compuesto se le conoce como el problema de la primalidad.

Así, a primera vista, este parece un problema "fácil" (más que a "fácil" la pregunta debería hacer referencia a poco costoso) y basándonos en la criba de Eratóstenes podríamos probar a dividir el número impar en cuestión (evidentemente éste debe ser impar, ya que el único número primo par es el 2) entre todos los números enteros impares positivos comprendidos entre el 3 y el entero más próximo por defecto a la raíz cuadrada del número dado, pero esto es claramente inaceptable cuando el número en cuestión es lo suficientemente grande.

Una vez que desechamos este método, la siguiente "tentación" que podemos tener para dar respuesta a esta pregunta es pensar en factorizar dicho número con métodos más modernos, pero, tal y como he comentado al principio de este post, ésto, de momento, tampoco es posible en un tiempo razonable para números lo suficientemente grandes, como es el caso de RSA.

¿Es ésto importante?. Pues sí, ya que conviene recodar que RSA, el criptosistema de clave pública más utilizado en la actualidad, se basa precisamente en seleccionar aleatoriamente dos números primos grandes (cada uno de ellos del orden de 200 dígitos decimales) para generar el par de claves para cada usuario (pública y privada).

Entonces: ¿cómo se hace en la práctica para seleccionar dos números primos grandes?. Afortunadamente, existen algoritmos probabilísticos, mucho más eficientes que los de factorización, que nos pueden decir con un alto grado de confianza si un número dado es primo o compuesto, ésto es lo que se conoce como tests de primalidad, es decir, se trata de algoritmos no deterministas (no hay certeza matemática del resultado obtenido) que intentan verificar la hipótesis de que un determinado número es compuesto y si no lo consiguen aceptan que es primo con un cierto nivel de confianza.

En un post posterior, para no hacer éste excesivamente largo, compartiré lo que que voy aprendiendo sobre los tests de primalidad y pondré algunos ejemplos.  

5.- ¿Existen diferentes tipos de números primos?:

Hay multitud de clases o tipos de números primos, es decir, de subconjuntos del conjunto de números primos formados por aquellos que comparten unas determinadas características y que reciben un nombre colectivo para identificarlos. Así, entre muchas otras clases, nos encontramos, por ejemplo, con los números primos: pitagóricos, de Wieferich, etc., pero quizá los tipos de números primos con mayor aplicación en la criptografía son losprimos fuertesy losprimos seguros.

También, como en el caso anterior, en un post posterior compartiré lo que voy aprendiendo sobre los tipos de números primos con aplicación en la criptografía,

Criptografía (XLVI): RSA y los números primos grandes, ¿"la pescadilla que se muerde la cola"?

$
0
0
Tal y como he venido comentado en la serie de posts dedicados al algoritmo RSA, quizá el criptosistema de clave pública más utilizado en la actualidad, éste se basa en la elección de dos números primos aleatorios lo suficientemente grandes (actualmente del orden de 200 dígitos decimales cada uno de ellos) para generar el par de claves (pública y privada) correspondiente a cada usuario.

También decía en un post anterior que no es trivial conocer si un número lo suficientemente grande es primo o compuesto y que, para ello, podíamos caer en la "tentación" de intentar factorizarlo. Craso error, pues tal y como también he venido insistiendo en esta serie de posts, nos enfrentaríamos precisamente con aquello en lo que se basa la fortaleza de este cifrado: actualmente ésto no es posible en un tiempo mínimamente razonable.

Entonces: ¿Cómo seleccionamos aleatoriamente los dos números primos grandes para generar el par de claves correspondiente a un usuario?, es decir, ¿Cómo "determinamos" que los números primos aleatorios elegidos son primos sin intentar factorizarlos?, ¿Es la "pescadilla que se muerde la cola"?.

Pues no, tal y como también decía en este post, afortunadamente existen algoritmos probabilísticos que nos pueden decir con un alto nivel de confianza si un número dado es primo, aunque no haya certeza matemática (100%) al respecto.

Veamos uno de los tests de primalidad más utilizados, el de Miller-Rabiny algunos ejemplos.

Si no lo he entendido mal, el algoritmo para aplicar este test a un número dado para conocer si éste es primo (con un alto nivel de confianza) o compuesto podría ser el siguiente:
Veamos algunos ejemplos:

1.- Partiendo del ejemplo que vengo utilizando en esta serie de posts: ¿es el 997 un número primo?:

Aunque con un número tan pequeño es trivial conocer si es primo o no (ya sabemos que sí lo es) veamos que ocurre aplicando el test de primalidad de Miller-Rabin:
2.- Pero quizá no sea tan trivial saber si el 286.467.789.841 es un número primo. Veamos que ocurre en esta ocasión.
Y como para demostrar que un número es compuesto no hay mejor demostración que enseñar los factores no triviales cuyo producto da ese número: 298.817 x 958.673 = 286.467.789.841.

3.- Y, finalmente: ¿es el 275.415.303.169 un número primo?:
En este caso, el test nos dice que probablemente (con un muy elevado nivel de confianza) este número es primo, aunque como digo no se trata de un test determinista y por tanto creérselo es una cuestión de fe :), aunque yo sé que efectivamente sí lo es.

Criptografía (XLVII): Descifrado RSA, ¿un "trabajo de chinos"?

$
0
0
Uno de los estereotipos con relación a los chinos es que éstos son muy laboriosos, pacientes y meticulosos en el trabajo, por lo que entiendo que el dicho popular "trabajo de chinos" hace referencia a aquel que es largo, tedioso y/o complicado.

Pero, ¿qué tiene que ver ésto con el descifrado utilizando el algoritmo RSA?.

Me explico: tal y como sabemos, en criptografía híbrida, el algoritmo RSAse emplea para cifrar la clave de sesión (un número aleatorio correspondiente a cada mensaje particular) con la clave pública del receptor y que después este último descifra utilizando su clave privada (criptografía asimétrica) para, a su vez, poder después descifrar el criptograma empleando la clave de sesión (criptografía simétrica).

Supongamos que para cifrar el texto en claro se utiliza el algoritmo de criptografía simétrica AES (longitud de la clave de 256 bits). Por tanto, para cifrar la clave de sesión (k) mediante RSA se realizará la siguiente operación: c = ke mod n, donde k tiene un tamaño de 256 bits, para e se recomienda utilizar valores relativamente pequeños para forzar que d tenga un tamaño en bits del orden del módulo, y n de 2048 bits.

Por consiguiente, para el descifrado de la clave de sesión se realizará la siguiente operación: k = cd mod n, donde c puede tener un tamaño de 2048 bits, d será del orden de 2048 bits y n de 2048 bits, lo que efectivamente tiene pinta de ser, por costoso, un auténtico "trabajo de chinos".

Bueno, pues que lo resuelvan los chinos..., y efectivamente también así es, ya que para simplificar los cálculos en el descifrado se suele utilizar el teorema chino del resto.

Utilizando este teorema y mediante los números primos p y q cuyo producto es el módulo (n), los cálculos a realizar en el descifrado, tal y como veremos más adelante, serán sensiblemente más rápidos. Nótese que los números p y q son secretos y, por tanto, que ésto sólo puede realizarlo el receptor del mensaje.

Para ello, junto con su clave privada (d, n), el receptor debe guardar los números primos p y q, y, además, para aplicar de forma óptima este teorema en el descifrado, los siguientes valores:

1.- p1 = p-1 mod q

2.- dp = d mod (p – 1)

3.- dq = d mod (q  1)

De esta forma sólo debemos calcular estos valores un sola vez y evitamos tener que hacerlo en cada descifrado.

Ahora, por lo que he entendido, el descifrado se realizaría de la siguiente manera:

1.- Calculamos:

1.1.- cp = c mod pcq = c mod q

1.2.- k1 = cpdp mod pk2 = cqdq mod q

2.- Resultado: k = k1 + p (((k2  k1) p1 )mod q)

Veamos un ejemplo, pero esta vez con números un poco más grandes de aquellos que vengo utilizando en esta serie de posts, aunque todavía mucho más pequeños de los que se emplean actualmente en RSA. De esta forma veremos mejor la ventaja que supone aplicar este teorema en el descifrado.

Previamente al ejemplo, genero un par de claves y realizo la operación de cifrado de una clave de sesión (k):

1.- p = 26.317; q = 30.269; n = pq26.317 x 30.269 = 796.589.273j(n) = (p  1)(q  1) = 26.316 x 30.268 = 796.532.688; e = 65.537; mcd(e, j(n)) = mcd(65.537, 796.532.688) = 1; d = inv(e, j(n)) = inv(65.537, 796.532.688) = 329.140.817 

2.- Clave pública del receptor (e, n): (65.537, 796.589.273)

3.- Clave privada del receptor (d, n): (329.140.817, 796.589.273)

4.- Clave de sesión (k) a cifrar mediante RSA: 505.316.708

5.- Cifrado: c = ke mod n = 505.316.70865.537 mod 796.589.273 = 670.835.545

Y ahora el ejemplo: el receptor tiene guardados, junto a su clave privada (329.140.817, 796.589.273), p = 26.317, q = 30.269 y  los siguientes valores previamente calculados: p1 = p-1 mod q = 17.685; dp = d mod (p – 1) = 329.140.817 mod 26.316 = 6.605; dq = d mod (q  1) = 329.140.817 mod 30.268 = 6.585, con lo que, si lo he entendido bien, el descifrado sería como sigue:

1.- cp = c mod p = 670.835.545 mod 26.317 = 15.215; cq = c mod q =  670.835.545 mod 30.269 = 13.967

2.- k1 = cpdp mod p = 15.2156.605 mod 26.317 = 3.991; k2 = cqdq mod q =  13.9676.585 mod 30.269 = 6.022

3.- k = k1 + p (((k2  k1) p1) mod q) = 3.991 + 26.317 (((6.022  3.991) 17.685) mod 30.269) = 3.991 + 26.317 x 19.201 = 505.316.708

Y, por tanto, parece que "los chinos han hecho bien su trabajo" :), ya que como se puede observar el resultado del descifrado coincide con la clave de sesión (k) que se ha cifrado.

Nótese que el paso más costoso del descifrado es el paso 2, en el que se realizan dos operaciones de exponenciación modular con bases con una longitud de 14 bits, exponentes de 13 bits y módulos de 15 bits, mientras que si no utilizáramos este teorema el descifrado se realizaría mediante la siguiente operación: k = cd mod n = 670.835.545329.140.817 mod 796.589.273 = 505.316.708, es decir, una operación de exponenciación modular con una base de longitud 30 bits, un exponente de 29 bits y un módulo de 30 bits.

Con lo que tal y como se observa, la ventaja fundamental de aplicar este teorema consiste en que mientras la clave privada (d) tiene una longitud del orden del tamaño del módulo (en nuestro caso 29 y 30 bits, respectivamente), dp y dq tienen una longitud aproximadamente de la mitad (en nuestro caso 13 bits) y, además, estos dos últimos valores pueden calcularse previamente una sola vez y guardarse para ser utilizados en descifrados posteriores.   

Criptografía (XLVIII): cifrado autoclave

$
0
0
En este post, antes de continuar con las entradas relativas a la criptología moderna, vuelvo a referirme a un criptosistema clásico, el cifrado autoclave.

Se trata de una variante del cifrado de Vigenère en la que se utiliza una clave primaria que se emplea para cifrar/descifrar los primeros caracteres y el cifrado/descifrado del resto se realiza utilizando como siguientes caracteres de la clave los del propio texto en claro, es decir, realmente la clave consiste en la concatenación de la clave primaria más el texto en claro.

De esta forma se consigue que la clave sea más larga que el propio mensaje a cifrar y, entre otras cosas, que no sea posible el criptoanálisis mediante el método Kasiski, ya que no se emplea una clave periódica.

Veamos un ejemplo:

1.- Texto en claro a cifrar (M): EJEMPLOCIFRADOAUTOCLAVE.

2.- Clave primaria (Kp): CLAVE.

3.- Clave (K)Kp & M.

Es decir:
4.- Cifrado: de la misma forma que en el cifrado de Vigenère, es decir, utilizando la tabla con los caracteres de español ("Ñ" incluido) o, lo que es lo mismo, la función de cifrado indicada en este post.
Ek(m1) = (m1 + k1) mod 27 = (E + C) mod 27 = (4 + 2) mod 27 = 6 = G = c1
Ek(m2) = (m2 + k2) mod 27 = (J + L) mod 27 = (9 + 11) mod 27 = 20 = T = c2
Ek(m3) = (m3 + k3) mod 27 = (E + A) mod 27 = (4 + 0) mod 27 = 4 = E = c3
Ek(m4) = (m4 + k4) mod 27 = (M + V) mod 27 = (12 + 22) mod 27 = 7 = H = c4
Ek(m5) = (m5 + k5) mod 27 = (P + E) mod 27 = (16 + 4) mod 27 = 20 = T = c5
Ek(m6) = (m6 + k6) mod 27 = (L + E) mod 27 = (11 + 4) mod 27 = 15 = O = c6
...
Ek(m11) = (m11 + k11) mod 27 = (R + L) mod 27 = (18 + 11) mod 27 = 2 = C = c11
...

Y así sucesivamente hasta obtener el texto cifrado o criptograma: GTEHTO...

5.- Descifrado:

5.1.- En primer lugar se descifran los caracteres del criptograma correspondientes a los caracteres de la clave primaria (Kp), que en nuestro caso es "CLAVE":
DKp(c1) = (c1 - kP1) mod 27 = (G - C) mod 27 = (6 - 2) mod 27 = 4 = E = m1
DKp(c2) = (c2 - kP2) mod 27 = (T - L) mod 27 = (20 - 11) mod 27 = 9 = J = m2
DKp(c3) = (c3 - kP3) mod 27 = (E - A) mod 27 = (4 - 0) mod 27 = 4 = E = m3
DKp(c4) = (c4 - kP4) mod 27 = (H - V) mod 27 = (7 - 22) mod 27 = 12 = M = m4
DKp(c5) = (c5 - kP5) mod 27 = (T - E) mod 27 = (20 - 4) mod 27 = 16 = P = m5

5.2.- Después se continúa descifrando el criptograma utilizando los caracteres descifrados hasta el momento (en nuestro caso los cinco primeros caracteres del texto en claro) como los siguientes caracteres de la clave:

DK(c6) = (c6 - m1) mod 27 = (O - E) mod 27 = (15 - 4) mod 27 = 11 = L = m6
...

Y así sucesivamente:

DK(c11) = (c11 - m6) mod 27 = (C - L) mod 27 = (2 - 11) mod 27 = 18 = R = m11
...

hasta obtener el texto en claro completo: EJEMPL...

Criptografía (XLIX): el algoritmo DES (I)

$
0
0
DES (Data Encryption Standard) fue desarrollado por IBM a petición de la Oficina Nacional de Estandarización (National Bureau of Standards) de los Estados Unidos. Su diseño se basó en otro algoritmo anterior, Lucifer, y fue adoptado como estándar de cifrado en 1976 por el Gobierno de los EE.UU.

Es un algoritmo de cifrado simétrico (se utiliza la misma clave para cifrar y para descifrar) por bloques (la información a cifrar se divide en bloques y se aplica el algoritmo a cada uno de ellos) que se basa en una estructura denominada Red de Feistel (cifrado de producto iterativo de n rondas en el que la salida de cada una de ellas se usa como entrada en la siguiente).

Este algoritmo opera sobre bloques de 64 bits del texto en claro, dividiendo cada uno de ellos en dos mitades, L (los 32 bits de la izquierda) y R (los 32 bits de la derecha), y emplea una clave de 56 bits.

Básicamente, el cifrado consiste en una permutación inicial, una Red de Feistel de 16 rondas (16 iteraciones en las que se repiten una serie de operaciones: permutaciones, aritmética modular y sustituciones. Ver conceptos de difusión, confusión y cifrado de producto en este post) y una permutación final.

En principio la longitud de la clave (K) es de 64 bits, pero el bit menos significativo de cada byte se ignora, por lo que sólo se emplean 56 bits.

Si no lo he entendido mal, su funcionamiento sería el siguiente:

1.- Como paso previo al cifrado, a partir de la clave de 64 bits se calculan 16 subclaves (Ki) de 48 bits cada una (una para cada ronda).

1.1.- Permutación de los bits de K conforme a la posición de cada uno de ellos que se indica en la siguiente tabla:
Nótese que en esta tabla no figuran los bits menos significativos de cada byte (8, 16, 24, 32, 40, 48, 56 y 64), por lo que éstos son ignorados (como he dicho antes, en la práctica se emplean 56 bits de la clave).

Pongo un ejemplo:
1.2.- Ahora, los bits de la mitad izquierda (C0) y de la mitad derecha (D0), obtenidas tras la permutación PC-1, ambas de 28 bits, se van rotando circularmente a la izquierda conforme al número de bits a desplazar a la izquierda que se indica en la siguiente tabla:
Es decir, el número de bits a desplazar a la izquierda es 2, excepto para las iteraciones 1, 2, 9 y 16 en las que se desplaza sólo 1 bit a la izquierda.

En nuestro ejemplo:
1.3.- Tras cada una de las iteraciones anteriores se aplica la permutación PC-2 a  los bits de la concatenación de Ci || Di (donde £ i £ 16), conforme a la posición de cada uno de ellos que se indica en la siguiente tabla:
Y, de esta forma, se obtienen las 16 subclaves (Ki; donde £ i £ 16); como he dicho antes, cada una de ellas con una longitud de 48 bits. Siguiendo con nuestro ejemplo:
Hasta el momento, gráficamente:
Y ahora ya se está en disposición de cifrar el texto en claro.

2.- Cifrado: Supongamos que vamos a cifrar un bloque (64 bits) del texto en claro. El siguiente:

M = 0100 0101 0100 1010 0100 0101 0100 1101 0101 0000 0100 1100 0100 1111 0100 1101


2.1.- Se aplica una permutación inicial (IP) a los bits del bloque a cifrar conforme a la posición de cada uno de ellos que se indica en la siguiente tabla:
En nuestro ejemplo:
2.2.- A partir de aquí el algoritmo realiza 16 rondas utilizando una función (f), de la siguiente manera:
Es decir, en cada ronda, la mitad derecha pasa a ser la mitad izquierda de la siguiente iteración y la mitad izquierda, a la que se suma módulo 2 (operador lógico XOR u o-exclusivo) el resultado de la función f, pasa a ser la mitad derecha.

Gráficamente:
La función f consta de: una permutación de expansión (E) - que transforma el bloque de 32 bits de la entrada en uno de 48 bits, permutando los bits que recibe y duplicando algunos de ellos -, una operación XOR con el valor de la subclave correspondiente (Ki), 8 operaciones de sustitución aplicadas a cada uno de los 8 bloques de 6 bits en los que se divide el resultado de la operación XOR anterior y otra permutación (P).

Gráficamente:
2.2.1.- La permutación de expansión (E) se realiza conforme a la posición de cada uno de los bits de entrada que se indica en la siguiente tabla:
Nótese que algunos de los bits que recibe (32 bits) se duplican para obtener una salida de 48 bits, con objeto de poder realizar la operación XOR con la subclave (Ki) correspondiente, que tiene una longitud de 48 bits.

En nuestro ejemplo, para la primera iteración (entrada R0):
2.2.2.- Operación XOR con el valor de la subclave correspondiente:
En nuestro ejemplo y para la primera ronda:
2.2.3.- Las sustituciones se realizan mediante unas tablas denominadas S-Cajas (en inglés S-Boxes, Substitution Boxes).

Para ello, en primer lugar se divide el resultado anterior en 8 bloques de 6 bits cada uno, de la siguiente manera:
Y, posteriormente, cada uno de estos bloques es la entrada a su respectiva S-Caja, cada unas de las cuales determina la sustitución a realizar de la siguiente manera:

El primer y último bit de cada bloque (Bi) indican la fila de la S-Caja (Si) a seleccionar y los cuatro bits centrales determinan la columna, devolviéndose el valor (4 bits) que se encuentra en la intersección de ambas.

En nuestro ejemplo, para la primera ronda y primera S-Caja (S1):
Las tablas de las S-Cajas son las siguientes:
2.2.4.- Por último, el resultado de la función f de cada ronda se obtiene aplicando una permutación (P) a la concatenación (32 bits) de los resultados obtenidos tras realizar cada una de las sustituciones anteriores, que devuelve un bloque también de 32 bits.
Y se repite el paso 2.2. hasta completar las 16 rondas.

2.3.- Finalmente, se aplica una permutación inversa a la permutación inicial (IP-1), conforme a la posición de cada uno de los bits de la concatenación de R16 y L16 obtenidos en la última ronda:
El resultado de aplicar esta permutación final es el criptograma (C).

Para ver si lo he entendido correctamente (con tanta confusión y difusión reconozco estar yo mismo un tanto confuso y difuso :)), en el próximo post pondré el resultado completo del cifrado del ejemplo y en otro posterior su descifrado, aunque ya adelanto que para el descifrado bastará con aplicar las subclaves (Ki) en orden inverso.

Criptografía (L): el algoritmo DES (II)

$
0
0
En el post anterior decía que iba a completar el ejemplo que puse de cifrado utilizando el algoritmo DES. Lo intento, pero bien entendido que sólo concluiré que es correcto, más o menos, cuando en el siguiente post consiga descifrar el criptograma (C) que obtengo en éste. Si no lo consigo algo habré hecho mal y corregiré este post y el anterior.

Como paso previo al cifrado debemos obtener, a partir de la clave (K), de 64 bits, las 16 subclaves (Ki), de 48 bits cada una, que se emplearán en las 16 rondas de la red de Feistel de las que consta este algoritmo, una subclave por ronda.

Ya expliqué en el post anterior como hacerlo, siendo la clave de nuestro ejemplo y las subclaves calculadas a partir de ésta las siguientes:
Y ya estamos en disposición de cifrar un texto en claro, para lo que hay que recordar que este algoritmo se aplica sobre bloques de 64 bits del mismo. En nuestro ejemplo proponía cifrar el siguiente bloque:

- En binario:

M = 0100010101001010010001010100110101010000010011000100111101001101

- En hexadecimal:

M = 454A454D504C4F4D

1.- Permutación inicial (IP) de los bits del bloque a cifrar:
2.- Red de Feistel de 16 rondas:

2.1.- Primera iteración:
2.2.- Segunda iteración:
2.3.- Tercera iteración:
2.4.- Cuarta iteración:
2.5.- Quinta iteración:
2.6.- Sexta iteración:
2.7.- Séptima iteración:
2.8.- Octava iteración:
2.9.- Novena iteración:
2.10.- Décima iteración:
2.11.- Undécima iteración:
2.12.- Duodécima iteración:
2.13.- Decimotercera iteración:
2.14.- Decimocuarta iteración:
2.15.- Decimoquinta iteración:
2.16.- Decimosexta iteración:
3.- Permutación final (IP-1) de los bits de la concatenación R16 || L16:
Con lo que el criptograma (C) sería:

- En binario:

C = 1001101111111011111110111111010011010000111110010001011000000100

- En hexadecimal:

C = 9BFBFBF4D0F91604


Lo dicho, en el siguiente post, para comprobar si lo he comprendido y he hecho correctamente, realizaré el descifrado de este criptograma. 

Criptografía (LI): el algoritmo DES (III)

$
0
0
En el post anterior puse un ejemplo de cifrado utilizando el algoritmo DES y decía que en éste, para ver si lo he comprendido y he hecho correctamente, voy a descifrar el criptograma que obtuve.

De forma análoga que en el cifrado, como paso previo al descifrado debemos obtener, a partir de la clave (K), de 64 bits, las 16 subclaves (Ki), de 48 bits cada una, que se emplearán en las 16 rondas de la red de Feistel de las que consta este algoritmo, una subclave por ronda.

Ya expliqué en un post anterior como hacerlo, siendo la clave de nuestro ejemplo y las subclaves calculadas a partir de ésta las siguientes:
Y ya estamos en disposición de descifrar el criptgograma, para lo que hay que recordar que en este post decía que basta con aplicar las sucbclaves (Ki) en orden inverso que en el cifrado. En nuestro ejemplo el criptograma obtenido es el siguiente:

- En binario:

C = 1001101111111011111110111111010011010000111110010001011000000100

- En hexadecimal:

C = 9BFBFBF4D0F91604


1.- Permutación inicial (IP) de los bits del bloque del criptograma a descifrar:
2.- Red de Feistel de 16 rondas (aplicando las subclaves en el orden inverso al cifrado):

2.1.- Primera iteración:
2.2.- Segunda iteración:
2.3.- Tercera iteración:
2.4.- Cuarta iteración:
2.5.- Quinta iteración:
2.6.- Sexta iteración:
2.7.- Séptima iteración:
2.8.- Octava iteración:
2.9.- Novena iteración:
2.10.- Décima iteración:
2.11.- Undécima iteración:
2.12.- Duodécima iteración:
2.13.- Decimotercera iteración:
2.14.- Decimocuarta iteración:
2.15.- Decimoquinta iteración:
2.16.- Decimosexta iteración:
3.- Permutación final (IP-1) de los bits de la concatenación R16 || L16:
Con lo que el texto en claro (M) sería:

- En binario:

M = 0100010101001010010001010100110101010000010011000100111101001101

- En hexadecimal:

M = 454A454D504C4F4D

Como se observa, he obtenido el mismo texto en claro (M) que en el post anterior, por lo que concluyo que tanto el cifrado como el descifrado son correctos.

'Habemus' Troll

$
0
0
¡Ya era hora!.

Tras exactamente 2.434 días de que naciera este modesto blog, con 352 entradas y 370 comentarios hasta el momento, al fin y como cualquier blog que se precie,

¡Ya tenemos nuestro propio Troll!.

Pero, antes que nada, veamo la definición de Troll en la wikipedia:

"Un troll otrol es un vocablo de Internet que describe a una persona que sólo busca provocar intencionadamente a los usuarios o lectores, creando controversia, provocar reacciones predecibles, especialmente por parte de usuarios novatos, con fines diversos, desde el simple divertimento hasta interrumpir o desviar los temas de las discusiones, también trollean páginas de wikipedia o bien provocar flamewars, enfadando a sus participantes y enfrentándolos entre sí. El troll puede ser más o menos sofisticado, desde mensajes groseros, ofensivos o fuera de tema, sutiles provocaciones o mentiras difíciles de detectar, con la intención en cualquier caso de confundir o provocar la reacción de los demás".

Aunque el origen etimológico de este término parece que nada tiene que ver con "El Señor de los anillos", tal y como nos aclara también la wikipedia: su origen más probable es el de «morder el anzuelo» o «morder el anzuelo mucho más» (troll es un tipo de pesca en inglés), permítaseme la licencia de las imágenes que ilustran este post, ya que soy un fan de Tolkien y porque creo que estos seres encajarían mejor como origen etimológico de este término.

Pues bien, como decía, ya nos empezábamos a preocupar("¡menuda mierda de blog que tenemos, no comenta ni un solo Troll!"), pero esto se acabó: ¡Ya tenemos nuestro propio Troll!. He borrado sus comentarios y no voy a reproducirlos porque, como todos sabemos, hay que tener mucho cuidado a la hora de alimentarles, es más, no se les debe dar de comer nunca porque mutan a subespecies que dan mucho más la tabarra.

Pero veamos, en concreto, a qué subespecie pertenece este Troll. Para ello fijémonos en varias de las características definitorias que nos pueden dar pistas para su catalogación: se ampara en el anonimato, sólo sabe poner groserías y carece de educación. Basándome en estas apreciaciones objetivas, yo diría que se trata de un Troll "tontolano" (bueno, ya sé que no es muy académico, pero es que no me encajaba exactamente en ninguna de las subespecies descritas hasta la fecha). En definitiva, creo que estamos ante una nueva subespecie aún sin catalogar y a la que me permito bautizar.  

Por favor, querido Troll (tú y yo sabemos quién eres), apúntate el número 1 para que cuando vuelvas a comentar en este blog te identifiques como Troll#1, así todos sabremos que eres tú otra vez, para no equivocarte con otros miembros de tu misma especie que nos visiten, ya que para nosotros tú siempre serásnuestro Troll.

En la medida que vayan visitándonos otros especímenes que pululan por Internet iremos escribiendo nuevos posts de bienvenida, catalogándoles y distinguiéndoles con el número correspondiente.

Criptografía (LII): ataque de intermediario a RSA

$
0
0
En anteriores posts de este blog he tratado sobre diferentes ataques teóricamente posibles al cifrado RSA, pero que tal y como decía, al menos actualmente, son ineficientes con la potencia de cálculo de los ordenadores actuales. Sin embargo hay otros ataques posibles y que pueden tener más probabilidades de éxito.

Tal y como también he dicho en anteriores posts de esta serie sobre criptografía:

"El eslabón más débil de la cadena de seguridad (y la criptografía no es una excepción) lo constituimos las personas".

Es decir, podemos tener un criptosistema muy robusto (muy seguro conceptualmente), como es el caso de RSA, pero si las personas que lo administramos y/o utilizamos no hacemos un uso adecuado del mismo éste podría ser "roto" con relativa facilidad.

En este post, como ejemplo de ésto, me voy a referir al ataque de intermediario (MitM, por las siglas en inglés de: "Man-in-the-Middle"), que, aunque en el título de este post lo he indicado como ataque al cifrado RSA, realmente puede emplearse para atacar cualquier criptosistema de clave pública.

En este tipo de ataques el atacante no se hace con la clave privada de los usuarios que intercambian entre sí mensajes cifrados, pero está en disposición de leerlos (descifrarlos y obtener así el texto en claro) e incluso de modificarlos, sin que emisor ni destinatario se den cuenta de ello.

Supongamos que un atacante (C) tiene acceso al directorio donde se encuentran las claves públicas de dos usuarios (A y B), entonces podría almacenar ambas claves y sustituirlas por otras dos previamente generadas por él y, por tanto, de las que dispone de sus respectivas claves privadas, o bien, si el intercambio de claves públicas entre A y  B se produce mediante sendas comunicaciones por un canal no seguro y C es capaz de interceptarlas, entonces C podría enviar a cada uno de ellos una clave pública generada por él haciéndoles creer a ambos que la clave pública que reciben es la correspondiente a la otra parte.
De esta forma, B cree disponer de la clave pública de A (KA), cuando realmente es una clave pública de C (KC1), y lo mismo le ocurre a A, que no dispone de la clave pública de B(KB) sino de otra clave pública generada por C (KC2), estando este último en disposición de leer los mensajes cifrados que se intercambien A y B, e incluso, como ya he dicho, de modificarlos. Todo ello sin que ni A ni B se den cuenta de que sus comunicaciones están comprometidas.

Veamos cómo. Supongamos que A quiere mandar un mensaje cifrado a B, para lo que utilizaría la clave pública que cree que es de B pero que realmente es de C (KC2) y se lo enviaría a B. C intercepta el mensaje y lo descifra con la clave privada correspondiente a la clave pública con la que A lo cifró (K'C2) y obtiene el texto en claro, rompiendo así el secreto que se pretendía guardar. Después C puede o no alterar el mensaje, cifrarlo con la verdadera clave pública de B (KB) y enviárselo a B como si el emisor fuera A. B descifra el mensaje con su clave privada (K'B) y cree que nadie ha tenido acceso al mismo.

Este ataque funciona de igual forma en sentido contrario (mensaje de B a A) pero el atacante utilizaría para descifrar el mensaje la clave privada K'C1 y después lo volvería a cifrar con la verdadera clave pública de A (KA) y se lo enviaría a éste como si el emisor fuera B.

El ataque de intermediario, si no se toman medidas adecuadas para evitarlo, es posiblemente el más efectivo para "romper" un cifrado RSA y, como ya he dicho antes, cualquier otro criptosistema de clave pública.

Evidentemente, el problema en este caso consiste en que el emisor debe asegurarse de que la clave pública con la que va a cifrar los mensajes es realmente del destinatario al que van dirigidos y no de un atacante. Una forma de hacer esto consiste en la participación de una Autoridad de Certificación (CA por sus siglas en inglés) que a la hora de entregar la clave pública de un usuario (destinatario) a otro (emisor) garantice que ésta es realmente del primero.

Criptografía (LIII): ataque a RSA mediante factorización (IV)

$
0
0
En esta ocasión me referiré al método de factorización de Dixon, un algoritmo de propósito general.

Recordar que, tal y como comenté en un post anterior, mientras que en los algoritmos de propósito específico (Fermat, rho Pollard, p -1 Pollard,...) el tiempo de ejecución depende de las características propias de los dos factores primos (p y q) del módulo (n) a factorizar, en los de propósito general éste sólo depende del tamaño del módulo.

Antes que nada explico lo que he entendido sobre este método (espero no equivocarme mucho) y pongo un ejemplo con el número que vengo utilizando como módulo en los ejemplos de cifrado RSA.

Si no lo he entendido mal, la idea básica de este método es, dado un número n a factorizar, encontrar dos números x e y tales que x2ºy2 mod n, con lo que (x - y) (x + y) es un múltiplo de n, y, por consiguiente, tanto el mcd(x - y, n) como el mcd(x + y, n) nos entregarán un factor no trivial de n (distinto de 1 y n) siempre y cuando ni (xy) ni (x + y) sean múltiplos de n.

Supongamos que queremos factorizar n, el método consiste en:

a) Tomar una base (B) de números primos consecutivos, empezando en 2, unión con -1, es decir, B = {-1, p1p2p3,...}.

b) Después elegimos números enteros zi , tales que zi2 pueda factorizarse como el producto de potencias de elementos de la base (Bmod n , es decir: zi2 = (-1)e1 x (p1)e2 x (p2)e3 x (p3)e4 x ... mod n.

c) Cuando encontremos varios números que satisfagan la condición anterior (wj) buscamos un subconjunto de ellos en los que la suma de exponentes de cada elemento de la base (sk) sea par, y eso nos llevará a la congruencia buscada: (w1 x w2 ...)2 º ((-1)s1/2 x (p1)s2/2 x (p2)s3/2 x (p3)s4/2 x ...)2 mod n.

Es decir:
x2 º y2 mod n.

d) Con lo que tanto el mcd(x - yn) como el mcd(x + yn) es muy probable que nos entreguen un factor no trivial de n (distinto de 1 y n).

Ejemplo: sea n = 52.841.

a) Tomamos como Base: B{-1, 2, 3, 5}.

b) Elegimos como números enteros cuyo cuadrado se factoriza como el producto de potencias de elementos de la base, los siguientes:

(229)2 º (-1)1 x (2)4 x (3)0 x (5)mod 52.841
(514)2 º (-1)1 x (2)0 x (3)2 x (5)0 mod 52.841

c) (229 x 514)2 º (22 x 3 x 5)2 mod 52.841

Lo que nos da: (12.024)2 º (60)2 mod 52.841

d) mcd(12.024 - 60, 52.841) = 997, y , por tanto, hemos conseguido factorizar el módulo: 52.841 = 997 x 53.

Pero en la práctica: ¿cómo se implementa este método?. En un próximo post intentaré poner un algoritmo para ello, conforme a lo que he entendido, y aplicarlo a este mismo ejemplo. ¿Algún voluntario para incluirlo en forma de comentario?.
Viewing all 638 articles
Browse latest View live