Ecuaciones de congruencias lineales Una congruencia de la forma: ax ≡ b (mod m) donde m es un entero positivo, a y b son números enteros y x es una variable entera, se llama congruencia lineal o ecuación de congruencia lineal (lineal por aparecer la variable x como potencia de grado uno, únicamente). Resolver esta ecuación consiste (como en el caso de la aritmética entera) en encontrar todos los enteros x que satisfagan la ecuación diofántica equivalente ax+my=b. En el caso de Zm, la ecuación tendrá solución si y solo si mcd(a,m)|b , y en este caso tendrá exactamente d=mcd(a,m) soluciones distintas en Zm de la forma: x= x0 + (m.t)/d , t=0,1,2,...,d-1 en donde x0 es una solución particular de la ecuación diofántica ax + my = b. En el apartado dedicado al algoritmo de Euclides se indica como puede utilizarse este algoritmo para calcular una solución particular de una ecuación diofántica.
Sistemas de congruencias: el teorema chino del resto El sistema de congruencias: x ≡ c1 (mod m1) x ≡ c2 (mod m2) ............ x ≡ cr (mod mr)
donde mcd(mi,mj)=1 para todo i , j distintos, tiene solución única en Zm1.m2...mr (es decir, hay una única solución x para 0
Unidades en
Zm
Denotamos por Um al conjunto de elementos invertibles de Zm. Um es llamado por algunos autores como el conjunto reducido de residuos módulo m. Cuando m es primo, todos los enteros {1,...,m-1} son invertibles en Zm, por lo tanto el cardinal |Um | = m-1 En Zm se cumple que: • •
Si [a], [b] ∈ Um entonces [a].[b] ∈ Um y también [a]-1 ∈ Um Si [a] ∈ Um entonces [a].Um = Um
La función φ de Euler
Se define la función φ de Euler con la función φ: N ⇒ N que a cada n le hace corresponder el número de enteros x (1
Teoremas de Euler y de Fermat El teorema de Euler
Si [a] ∈ Um entonces [a]φ(m) = [1] en Zm. Por tanto, si un b ∈ Z verifica que mcd(m,b)=1 entonces bφ(m) ≡ 1 (mod m)
El Pequeño teorema de Fermat
Si p es primo y p no divide a a entonces: ap-1 ≡ 1 (mod p) Números pseudoprimos Si se cumpliese la implicación contraria en el teorema de Fermat (que si se cumpliere que ap-1 ≡ 1 (mod p) con a no múltiplo de p, entonces podría asegurarse que p es primo), tendríamos una forma inmediata de comprobar si un número dado es primo. Desgraciadamente, hay ciertos números compuestos que satisfacen el teorema de Fermat. A esta clase de números compuestos se la denomina números pseudoprimos.
Un ejemplo de número pseudoprimo es el 341=11.31, ya que se cumple que 2340 ≡ 1(mod 341). Para verificar el resultado de esa potencia, puede usarse el applet de exponenciación modular en esta nueva ventana
Test de primalidad y generación de números primos Tests de primalidad
Para números muy grandes, como los usados en sistemas criptográficos como el RSA, que llegan a tener tamaños de entre 512 y 2048 bits, no es viable en un tiempo razonable el tratar de factorizar un número para saber si es o no primo. Pero existen métodos probabilísticos que nos pueden decir con un alto grado de certeza si un número es primo o compuesto. A estos métodos se les llama tests de primalidad. El mismo teorema de Fermat nos proporciona un método probabilístico para ver si un número es primo o no. Si un número p satisface el pequeño teorema de Fermat es probable que sea primo, aunque como ya se ha visto no podemos estar seguros de ello, ya que hay números compuestos (los pseudoprimos) que igualmente pueden pasar ese test. A lo largo del tiempo se han inventado tests de primalidad más eficientes que el teorema de Fermat. Todos ellos tienen en común que dan un resultado probable sobre la primalidad de p con una probabilidad de error determinada, y mediante iteraciones sucesivas del método podemos obtener mayores grados de certeza sobre el resultado. Cuanto mayor grado de certeza queramos tener, más iteraciones del método habrá que hacer y más tiempo computacional tardará en terminar el test. Así, si usamos un test de primalidad, como el método de Lehmann o algún otro, que nos indica si un número p es primo con una probabilidad de error menor o igual que 0.5 en el peor caso, si repetimos el método para p (con distintos parámetros, claro) n veces seguidas, al final la probabilidad de error será de 1 contra 2n. Generación de números primos
A efectos prácticos, un algoritmo que se suele emplear en las aplicaciones (por ejemplo, como Matlab o Maple) para generar aleatoriamente un número primo p con n bits es el siguiente: 1. Generar un número aleatorio p de n bits. 2. Poner a uno el bit más significativo (así garantizamos que el número es de n bits) y el menos significativo (debe ser impar para poder ser primo)
3. Intentar dividir p por una tabla de primos precalculados (usualmente aquellos que sean menores que 2000). Esto elimina gran cantidad de números no primos de una forma muy rápida. Baste decir a título informativo que más del 99.8 % de los números impares no primos es divisible por algún número primo menor que 2000. 4. Ejecutar tests de primalidad sobre p para ver si es primo hasta el grado de certeza deseado 5. Si el test falla, incrementar p en dos unidades y volver al paso 3.
Aplicaciones del cálculo en congruencias Aritmética con números grandes
La mayoría de los procesadores no son tan distintos de nosotros a la hora de trabajar con enteros: trabajan mucho más rápido con números pequeños que con números grandes. Una importante consecuencia que puede llegar a deducirse de las propiedades de las congruencias modulares y del teorema chino del resto es que si consideramos un conjunto {m1, m2,..., mk} de números primos entre sí (es decir, que mcd(mi,mj)=1 para cada i, j distintos), entonces cualquier entero positivo n menor que m = m1. m2... mk se puede expresar mediante un vector o k-upla (r1,r2, ... ,rk), tal que los ri cumplan las siguientes condiciones: 1) 0 < ri
Ventajas de la aritmética modular para operar con números grandes
Las operaciones aritméticas con dos enteros grandes se pueden realizar entre las k-uplas o vectores que representan a ambos enteros. Las operaciones se realizan en paralelo módulo mi, para cada par de componentes i-ésimos análogos de los dos vectores. Además al ser los componentes de las k-uplas siempre menores que el módulo m, pueden realizarse cálculos que en aritmética entera desbordarían los registros de la unidad aritmética del ordenador. Supongamos como ejemplo que tenemos que trabajar con un hardware que sólo puede realizar aritmética entera sin signo de 4 bits. Tendríamos un rango de enteros de {0,...,15}. No podríamos hacer operaciones como 16x11 usando aritmética entera, pues el resultado desbordaría nuestras capacidades de cálculo y representación. Pero si consideramos los siguientes módulos primos entre sí: m1=13, m2=14, m3=15, con lo que m= 13.14.15= 2730 Entonces, representamos 16 como el vector (16 mod 13, 16 mod 14, 16 mod 15) = (3, 2, 1) y 11 se representa como el vector (11, 11, 11) Para multiplicar 16x11 multiplicamos los dos vectores en paralelo componente a componente: (3, 2, 1) x (11, 11, 11) = (33 mod 13, 22 mod 14, 11 mod 15) = (7, 8, 11) (7, 8, 11) es la representación del entero 176 = 16 x 11. Igualmente para sumar 16 + 11 = (3, 2, 1) + (11, 11, 11) = (1, 13, 12) que representa al número entero 27= (27 mod 13, 27 mod 14, 27 mod 15) En cambio no se podría con este sistema multiplicar, por ejemplo, 60 x 60, ya que su resultado excede a m=2730. Generación de números pseudoaleatorios
Lo primero que hay que notar acerca de los algoritmos generadores de números aleatorios que usan los ordenadores es que ¡los números que generan no son aleatorios!. Los ordenadores usan algoritmos determinísticos y por tanto es más correcto llamarles generadores de numeros pseudo-aleatorios, ya que generan una secuencia de números que eventualmente pueden volver a repetirse y solamente se aproxima a una secuencia aleatoria.
Las congruencias lineales se han utilizado tradicionalmente para la implementación de funciones generadoras de números pseudoaleatorios en las bibliotecas de programación de la mayoría de los lenguajes de programación clásicos como C, Fortran, Basic, etc. Los generadores congruenciales lineales de números aleatorios fueron propuestos por primera vez por D.H. Lehmer en 1951, y utilizan una congruencia lineal de la siguiente forma: Xn = (aXn-1+c) (mod M)
Los parámetros a,c y M deben ser elegidos cuidadosamente para asegurar un largo período (número de enteros generados antes de que se repita la secuencia) y que la secuencia generada tenga buenas propiedades estadísticas de aleatoriedad y uniformidad. Para empezar el algoritmo se requiere un valor inicial X0, al que se llama la semilla. Así, para referirnos a un generador congruencial lineal determinado usamos la notación GCL(a, c, M, X0). Cuando el generador utiliza como constante de incremento c=0, se le llama generador multiplicativo puro. Muchas veces se deja al programador elegir la semilla inicial, y se emplea entonces la notación GCL(a, c, M). Una vez que se obtiene el entero Xn puede dividirse (división real) entre M para obtener valores reales distribuidos uniformemente en [0,1). Algunas propiedades e inconvenientes de los GCL i. El módulo M es una cota superior del número de valores diferentes que puede tomar la semilla. ii. Cuando Xi vuelve a tomar el valor de la semilla inicial X0, la secuencia se repetirá cíclicamente. iii.
Todas las secuencias producidas por este tipo de generador si se prolongan lo suficiente (período) acaban en un ciclo que se repite indefinidamente
Un buen generador lineal tendrá un período tan largo como sea posible (es decir, M). Para los generadores mixtos (los que no son multiplicativos puros) este máximo se alcanza si y sólo si se cumplen las tres siguientes condiciones que fueron enunciadas por Donald Knuth en su famoso libro The Art of Computer Programming: 1. c es primo con M 2. a-1 es múltiplo de p para todo primo p que divida a M
3. a-1 es múltiplo de 4 siempre que M sea múltiplo de 4
Estas condiciones se cumplen, por ejemplo, si se escogen M=2k, a=4t+1, y c número impar, siendo t, k enteros mayores que 0. Los GCL son sencillos de implementar, pero en la práctica las secuencias pseudoaleatorias generadas presentan correlaciones altas entre los números generados en la secuencia, lo que les hace poco útiles como fuente de números aleatorios en simulaciones por computadora medianamente complejas. También el hecho de que la secuencia de números generados es totalmente predecible los hace inefectivos para la generación segura de bits aleatorios usables en criptografía. Ejemplos clásicos de GCLs • GCL(75, 0, 231-1): El generador multiplicativo inventado por IBM para su serie 360. Tiene el máximo período posible para un generador multiplicativo: M-1 (= 231-2). Se ha utilizado posteriormente en muchas otras ocasiones (por ejemplo MATLAB utiliza este generador), tanto que se le ha llamado "generador estándar mínimo". • GCL(65539, 0, 231):El generador RANDU (IBM, años 60). Su módulo y multiplicador fueron elegidos así para facilitar la computación de los valores generados. No tiene el período máximo, y sus propiedades estadísticas no son las mejores... •
GCL(259, 0, 215):. RANDU usado para microprocesadores de 16 bits.
•
GCL(1103515425, 12345, 232): El generador congruencial lineal empleado en el S.O. UNIX original.
Prueba generadores congruenciales lineales de números aleatorios Tablas y funciones hash
Un problema habitual en la programación: almacenar en una tabla una gran cantidad de datos alfanuméricos de forma que se puedan recuperar lo más rápidamente posible cuando se busque un dato determinado en esa tabla. Una posibilidad es mantener la tabla ordenada por un campo clave, de forma que mediante un algoritmo de tipo de búsqueda dicotómica o tipo Quicksearch, se pueda encontrar rápidamente el dato buscado empleando el menor número de pasos (comparaciones) posibles. La
desventaja de las tablas ordenadas es que las inserciones de nuevos datos resultan más costosas que en las tablas no ordenadas. Otra posibilidad es encontrar una función h(k), a a que llamaremos función hash, tal que dada una clave k nos devuelva directamente la posición que ocupa en la tabla el dato asociado a la clave k, sin necesidad de que la tabla esté ordenada. Además es deseable que en la medida de lo posible, h(k) no devuelva el mismo resultado para dos claves k distintas. Si se da el caso de que h(k1) y h(k2) devuelven un mismo valor, entonces ambas claves distintas tendrían que ocupar la misma posición o registro en la tabla, lo que evidentemente no puede ser. Se dice en estos casos que se ha producido una colisión y que h1 y h2 son claves sinónimas. La función h(k) debe tratar de evitar esto en la medida de lo posible. Lo que en principio puede parecer complicado, encontrar una función tan "conveniente", usando congruencias el asunto es bien sencillo... Recapitulando: necesitamos una función que transforme claves (normalmente enteros o cadenas de caracteres) en enteros en un rango [0..M-1], donde M es el número de registros de la tabla que podemos manejar con la memoria de que dispongamos. Como factores a tener en cuenta para la elección de la función h(k) están que minimice las colisiones y que sea relativamente rápida y fácil de calcular. Vamos a ver como puede conseguirse esto basándonos en las congruencias lineales. Hasing modular
En este caso la función hash se calcula simplemente como h(k) = k mod M, usando el 0 como el primer índice de la tabla hash de tamaño M, y M-1 será el último índice o posición disponible. Aunque la fórmula es aplicable a tablas de cualquier tamaño es importante elegir el valor de M con cuidado para evitar excesivos sesgos en la distribución de las claves. Una regla simple para elegir M es tomarlo como un número primo, lo más próximo posible a la cantidad de posiciones de memoria disponibles para la tabla. En cualquier caso existen reglas mas sofisticadas para la elección de M (ver Knuth), basadas todas en estudios teóricos de funcionamiento de los métodos congruenciales de generación de números aleatorios. Es evidente que en muchas ocasiones el dominio de valores posibles de las claves Ki es mucho más amplio que el dominio de los residuos
módulo M: {0,1,...,M-1}, por lo que necesariamente se produciran colisiones usando este tipo de funciones hash. Una elección correcta de M puede hacer bajar el número de colisiones esperadas. Un comentario breve sobre resolución de colisiones entre sinónimos. Una posible solución es mantener listas enlazadas de sinónimos, de forma que si en la posición h(k) no se encuentra el dato asociado a la clave, sino que esta ocupada por una clave sinónima, entonces se busca el dato correcto en la lista enlazada correspondiente para ese sinónimo. Pero hay otras posibilidades para resolver colisiones, aunque no vamos a profundizar en el tema. Dígitos de control
La aritmética modular se emplea a menudo en la vida diaria para validar códigos numéricos, caso del DNI, de los dígitos de control de una cuenta corriente bancaria, o del ISBN para la clasificación de libros. Veamos alguno de estos ejemplos: Dígitos de control de una cuenta corriente
Un número de cuenta o Código de Cuenta Cliente (CCC) es una cadena de 20 dígitos de la forma EEEEOOOODCNNNNNNNNNN. Los cuatro primeros dígitos (EEEE) representan el código de la entidad bancaria, los cuatro siguientes (OOOO) representan el código de la oficina donde se dio de alta la cuenta, los dos siguientes (DC) son dos dígitos de control y los 10 restantes (NNNNNNNNNN) representan el número de cuenta. Un número de cuenta se da por válido cuando los dígitos de control que aparecen en el código CCC coinciden con los dígitos de control que se calculan a partir del CCC. En concreto, el dígito D se calcula a partir del código de entidad (EEEE) y del código de oficina (OOOO) utilizando un algoritmo basado en asignar distintos pesos a los dígitos del código de entidad y de oficina y en la aritmética módulo 11. El algoritmo de cálculo de D es como sigue: 1. La tabla de pesos para los dígitos de control correspondientes es: pos. E0 E1 E2 E3 O0 O1 O2 O3 peso 4 8 5 10 9
7
3
6
2. Se calcula el valor ponderado siguiente: valor = ∑Ei.pi + ∑Oj.pj Donde pi y pj son los pesos del correspondiente dígito Ei u Oj, según la tabla anterior.
3. D = 11 - (valor mod 11) 4. Como quiera que sólo se permiten dígitos entre 0 y 9, si D=11 se reemplazaría por D=0; y D=10 se reemplazaría por D=1.
El dígito de control C se refiere al número de cuenta corriente (NNNNNNNNNN) del código CCC y se calcula de forma análoga al dígito anterior: 1. La tabla de pesos correspondiente es: pos. N0 N1 N2 N3 N4 N5 N6 N7 N8 N9 peso 1
2
4
8
5
10 9
7
3
6
2. Se calcula el valor ponderado siguiente: valor = ∑Ni.pi Donde pies el peso del correspondiente dígito Ni, según la tabla anterior. 3. C = 11 - (valor mod 11) 4. Como quiera que sólo se permiten dígitos entre 0 y 9, si C=11 se reemplazaría por C=0; y C=10 se reemplazaría por C=1.
El cálculo de la letra del DNI
Un número de DNI es válido cuando la letra calculada a partir del DNI coincide con la letra que aparece en el DNI (a veces se la llama "la letra del NIF"). La forma de calcular esta letra es de la siguiente forma: 1. Se calcula el resto de dividir el valor numérico del DNI entre 23. 2. Una vez se tiene ese resto, para encontar la letra correspondiente se utiliza la siguiente tabla que establece la relación entre el resto de la división efectuada y la letra que debe aparecer en el DNI: Resto 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 Letra T R W A G M Y F P D X B N J
Z D Q V H L
C K E
Validación del número ISBN
ISBN es el número que se utiliza universalmente para la catalogación de publicaciones impresas. Un número ISBN contiene distinta información identificadora de la editorial que publica y del título en cuestión. Consta de 9 dígitos decimales, que aparecen en grupos separados por guiones que pueden figurar en muy distintas posiciones,
seguidos de un dígito de control para la suma de verificación. Este dígito puede tomar valores entre 0 y 10, usándose la letra X para representar el valor 10. La forma de cálculo de ese dígito de control (checksum) es muy sencilla. Si representamos los 9 primeros dígitos como d1d2d3...d9, el décimo dígito se calcula como: d10 = (1.d1 + 2.d2 + 3.d3 + ... + 9.d9) mod 11
Introducción a la criptografía La palabra Criptografía proviene del griego "kryptos" que significa oculto, y "graphia", que significa escritura, y su definición según el dicccionario es "Arte de escribir con clave secreta o de un modo enigmático". La Criptografía es una técnica, o más bien un conjunto de técnicas, que originalmente tratan sobre la protección o el ocultamiento de la información frente a observadores no autorizados. Entre las disciplinas que engloba cabe destacar la Teoría de la Información, la Complejidad Algorítmica y la Teoría de números o Matemática Discreta, que como ya sabemos estudia las propiedades de los números enteros. A través de la criptografía la información puede ser protegida contra el acceso no autorizado, su interceptación, su modificación y la inserción de información extra. También puede ser usada para prevenir el acceso y uso no autorizado de los recursos de una red o sistema informático y para prevenir a los usuarios la denegación de los servicios a los que sí están permitidos. Modernamente, la criptografía es la metodología para proveer la seguridad de las redes telemáticas, incluyendo la identificación de entidades y autenticación, el control de acceso a los recursos, la confidencialidad de los mensajes transmitidos, la integridad de los mensajes y su no repudio. Breve historia de la criptografía
Entre el Antiguo Egipto e Internet, los criptogramas (los mensajes cifrados) han protagonizado buena parte de los grandes episodios históricos y un sinfín de anécdotas. Existen mensajes cifrados entre los artículos del Kamasutra, se usaron por gobernantes y militares ya en los primeros estados como Egipto, Babilonia, Roma... Abundan en los textos diplomáticos de toda época, indispensables para las órdenes militares y los ejércitos modernos en tiempos de guerra y, por supuesto, esenciales
en la actividad de los espías. Hoy en día, con las nuevas tecnologías el uso de la criptografía se ha extendido más allá de su tradicional esfera estatal o política, y es vital también para la actividad diaria de las empresas y ciudadanos particulares. Los primeros métodos criptográficos
Los espartanos utilizaron, hacia el 400 a.C., la Escitala, que puede considerarse el primer sistema de criptografía por transposición, es decir, que se caracteriza por ocultar el significado real de un texto alterando el orden de los signos que lo conforman. Los militares de la ciudad-estado griega escribían sus mensajes sobre una tela que envolvía una vara. El mensaje sólo podía leerse cuando se enrollaba la tela sobre un bastón del mismo grosor, que poseía el destinatario lícito del mensaje (¿el origen del "bastón de mando"?).
Fig. A- Representación del método de la escitala El método de la escitala era extremadamente sencillo, como también lo era el que utilizó Julio César, basado en la sustitución de cada letra por la situada tres puestos después en el alfabeto latino. A este cifrado por sustitución sencilla se le conoce como cifrado César. Los cifrados polialfabéticos
La criptografía resurgió en la Europa de la Edad Media y el Renacimiento, impulsada por las intrigas del papado y las ciudadesestado italianas. Fue un servidor del Papa Clemente VII, Grabiele de Lavinde, quien escribió el primer manual sobre la materia en el viejo continente. En 1466, León Battista Alberti, músico, pintor, escritor y arquitecto, concibió el sistema de sustitución polialfabética que emplea varios abecedarios, saltando de uno a otro cada tres o cuatro palabras. El emisor y el destinatario han de ponerse de acuerdo para fijar la posición relativa de dos círculos concéntricos, que determinará la correspondencia de los signos.
Fig. B- Discos de Alberti Un siglo después, Giovan Battista Belaso de Brescia instituyó una nueva técnica. La clave, formada por una palabra o una frase, debe transcribirse letra a letra sobre el texto original. Cada letra del texto se cambia por la correspondiente en el alfabeto que comienza en la letra clave. Este cifrado ha llegado hasta nuestros días como "Cifrado Vigenère", ya que su invención fue atribuida incorrectamente al diplomático francés Blaise de Vigenère, contemporáneo de Belaso y autor de famosos tratados sobre criptografía en el S. XVI. Pero los métodos clásicos mono y polialfabéticos distan mucho de ser completamente seguros. En algunos casos, basta hacer un simple cálculo estadístico para desentrañar los mensajes ocultos. Si se confronta la frecuencia habitual de las letras en el lenguaje común con la de los signos del criptograma, puede resultar relativamente sencillo descifrarlo. Factores como la longitud del texto, el uso o no de más de una clave o la extensión de esta juegan un papel muy importante, así como la intuición, un arma esencial para todo criptoanalista (rompedor de cifrados). En el siglo XIX Friederich Kasiski, un militar prusiano, publicó un ataque basado en métodos estadísticos que rompía los cifrados por sustitución polialfabética. El siglo XX y la II Guerra Mundial
El siglo XX ha revolucionado la criptografía. Retomando el concepto de las ruedas concéntricas de Alberti, a principios del siglo se diseñaron teletipos equipados con una secuencia de rotores móviles. éstos giraban con cada tecla que se pulsaba. De esta forma, en lugar de la
letra elegida, aparecía un signo escogido por la máquina según diferentes reglas en un código polialfabético complejo. Estos aparatos, se llamaron traductores mecánicos. Una de sus predecesoras fue la Rueda de Jefferson, el aparato mecánico criptográfico más antiguo que se conserva. La primera patente data de 1919, y es obra del holandés Alexander Koch, que comparte honores con el alemán Arthur Scherbius, el inventor de Enigma una máquina criptográfica a rotor que los nazis creyeron inviolable, sin saber que aceleraría su derrota. En efecto, en el desenlace de la contienda, hubo un factor decisivo y apenas conocido: los aliados eran capaces de descifrar todos los mensajes secretos alemanes.
Fig. C- Una máquina Enigma original de la S.G.M. Una organización secreta británica, en la que participó Alan Turing, uno de los padres de la informática y de la inteligencia artificial, había logrado desenmascarar las claves de Enigma y de su "hermana mayor" Lorenz, desarrollando más de una docena de artilugios -llamados las bombas- que desvelaban los mensajes cifrados. La máquina alemana se convertía así en el talón de Aquiles nazi, un topo en el que confiaban y que en definitiva, trabajaba para el enemigo. Paralelamente, Los códigos de la versión japonesa de Enigma (llamados Purple, violeta) se descifraron por un grupo de analistas, dirigidos por el comandante Joseph J. Rochefort. Su criptoanálisis fue vital para la victoria americana en la batalla de Midway. La existencia de Enigma y el hecho de que los aliados conociesen sus secretos fueron, durante mucho tiempo, dos de los secretos mejor guardados de la II Guerra Mundial. ¿La razón? Querían seguir sacándole
partido tras la guerra potenciando su uso en diversos países, que, al instalarla, hacían transparentes sus secretos para las potencias anglosajonas. La criptografía en la era de la informática
Finalizada la contienda, las nuevas tecnologías electrónicas y digitales se adaptaron a las máquinas criptográficas. Se dieron así los primeros pasos hacia los sistemas criptográficos más modernos, mucho más fiables que la sustitución y transposición clásicas. Hoy por hoy, se utilizan métodos que combinan los dígitos del mensaje con otros, o bien algoritmos de gran complejidad como el DES (inventado por IBM) y sus posteriores sucesores. Una de las aportaciones del último cuarto del s. XX son los sistemas de cifrado asimétrico o de clave pública (como RSA), en contraposición con todos los anteriores, que son criptosistemas simétricos o de clave privada, que usaban la misma clave para el cifrado y el descifrado del mensaje. La ventaja de estos sistemas es que permiten solucionar uno de los problemas de la criptografía clásica, la distribución de las claves secretas a los participantes en la comunicación. En la criptografía de clave pública, una de las claves puede hacerse pública sin que por ello la seguridad de la clave secreta se vea afectada. Lo cifrado con la clave secreta puede descifrarse con la pública y viceversa. Esta propiedad de los criptosistemas asimétricos permite también otras aplicaciones de estos criptosistemas, como la firma digital que es tan importante en las redes de telecomunicaciones hoy. Existen dos trabajos fundamentales sobre los que se apoya prácticamente toda la teoría criptográfica actual. Uno de ellos, desarrollado por Claude Shannon en sus artículos "A Mathematical Theory of Communication" (1948) y "Communication Theory of Secrecy Systems" (1949), sienta las bases de la Teoría de la Información y de la Criptografía moderna. El segundo, publicado por Whitfield Diffie y Martin Hellman en 1976, se titulaba "New directions in Cryptography", e introducía el concepto de Criptografía de Clave Pública, abriendo enormemente el abanico de aplicación de esta viejísima disciplina. Con la publicación del algoritmo RSA en 1977 por parte de los matemáticos Ron Rivest, Adi Shamir y Len Adleman la criptografía "moderna" o de clave pública alcanza su consolidación.
La criptografía y sus funciones en la seguridad de la información Con la criptografía se intenta garantizar las siguientes propiedades deseables en la comunicación de información de forma segura (a estas propiedades se las conoce como funciones o servicios de seguridad): Confidencialidad: solamente los usuarios autorizados tienen acceso a la información. Integridad de la información: garantía ofrecida a los usuarios de que la información original no será alterada, ni intencional ni accidentalmente. Autenticación de usuario: es un proceso que permite al sistema verificar si el usuario que pretende acceder o hacer uso del sistema es quien dice ser. Autenticación de remitente: es el proceso que permite a un usuario certificar que el mensaje recibido fue de hecho enviado por el remitente y no por un suplantador. Autenticación del destinatario: es el proceso que permite garantizar la identidad del usuario destinatario. No repudio en origen: que cuando se reciba un mensaje, el remitente no pueda negar haber enviado dicho mensaje. No repudio en destino: que cuando se envía un mensaje, el destinatario no pueda negar haberlo recibido cuando le llegue. Autenticación de actualidad (no replay) : consiste en probar que el mensaje es actual, y que no se trata de un mensaje antiguo reenviado. Criptología: criptografía y criptoanálisis
Conviene hacer notar que la palabra Criptografía sólo hace referencia al uso de códigos, por lo que no engloba a las técnicas que se usan para romper dichos códigos, conocidas en su conjunto como Criptoanálisis. En cualquier caso ambas disciplinas están íntimamente ligadas; no olvidemos que cuando se diseña un sistema para cifrar información, hay que tener muy presente su posible criptoanálisis, ya que en caso contrario podríamos llevarnos desagradables sorpresas. Finalmente, el término Criptología, aunque no está recogido aún en el Diccionario, se emplea habitualmente para agrupar tanto la Criptografía como el Criptoanálisis.
Criptosistemas de clave pública y privada Criptosistemas (sistemas de cifrado)
Puede definirse formalmente un criptosistema como una quintupla (M, C, K, E, D), donde: • •
M representa el conjunto de todos los mensajes sin cifrar (lo que se denomina texto claro, o plaintext) que pueden ser enviados. C representa el conjunto de todos los posibles mensajes cifrados, o criptogramas.
•
K representa el conjunto de claves que se pueden emplear en el criptosistema.
•
E es el conjunto de transformaciones de cifrado o familia de funciones que se aplica a cada elemento de M para obtener un elemento de C. Existe una transformación diferente Ek para cada valor posible de la clave k.
•
D es el conjunto de transformaciones de descifrado, análogo a E.
Todo criptosistema ha de cumplir la siguiente condición: Dk (Ek (m)) = m
es decir, que si tenemos un mensaje m, lo ciframos empleando la clave k y luego lo desciframos empleando la misma clave, obtenemos de nuevo el mensaje original m. Tipos de criptosistemas
Existen dos tipos fundamentales de criptosistemas o sistemas de cifrado: •
•
Criptosistemas simétricos o de clave privada. Son aquellos que emplean una misma clave k tanto para cifrar como para descifrar. Presentan el inconveniente de que para ser empleados en comunicaciones la clave k debe estar en posesión tanto en el emisor como en el receptor, lo cual nos lleva preguntarnos cómo transmitirles a los participantes en la comunicación esa clave de forma segura. Criptosistemas asimétricos o de clave pública, que emplean una doble clave (kp,kP). kp se la conoce como clave privada y kP se la conoce como clave pública. Una de ellas sirve para la transformación o función E de cifrado y la otra para la transformación D de descifrado. En muchos casos son intercambiables, esto es, si empleamos una para
cifrar la otra sirve para descifrar y viceversa. Estos criptosistemas deben cumplir además que el conocimiento de la clave pública kP no permita calcular la clave privada kp. Ofrecen un abanico superior de posibilidades, pudiendo emplearse para establecer comunicaciones seguras por canales inseguros puesto que únicamente viaja por el canal la clave pública, que sólo sirve para cifrar, o para llevar a cabo autenticaciones. Sin la clave privada (que no es deducible a partir de la clave pública) un observador no autorizado del canal de comunicación será incapaz de descifrar el mensaje cifrado.
En la práctica se emplea una combinación de estos dos tipos de criptosistemas, puesto que los criptosistemas asimétricos presentan el inconveniente de ser computacionalmente mucho más costosos que los primeros. En el mundo real se hace uso de la criptografía asimétrica para codificar las claves simétricas y poder así enviarlas a los participantes en la comunicación incluso a través de canales inseguros. Después se codificarán los mensajes (más largos) intercambiados en la comunicación mediante algoritmos simétricos, que suelen ser más eficientes.
Cifrados de sustitución polialfabeto Como ya se vio en el apartado dedicado a los criptosistemas monoalfabéticos, su principal debilidad es que el texto cifrado mantiene la misma distribución de frecuencia de caracteres que tiene el texto claro original, lo que hace que los cifrados monoalfabeto sean criptoanalizables por métodos estadísticos sencillos. Una posible mejora de los cifrados por sustitución es intentar métodos que destruyan esa correspondencia de frecuencias entre el mensaje en claro y el criptograma. Por ejemplo, utilizando varios alfabetos a la vez para el cifrado. En los cifrados polialfabéticos la sustitución aplicada a cada caracter varía en función de la posición que ocupe este dentro del texto claro. En realidad corresponde a una aplicación cíclica de n cifrados de sustitución monoalfabeto. Cifrado de Vigenère
Es un ejemplo típico de cifrado polialfabético cuya invención fue imputada erróneamente a Blaise de Vigenère, y que data del siglo XVI. La clave está constituida por una secuencia de símbolos del alfabeto K = {k0, k1, ... ,kd-1}, de longitud d, y que emplea la siguiente transformación congruente lineal de cifrado:
Ek (mi) = mi + k
(i mod d)
(mod n)
siendo mi el i-ésimo símbolo del texto claro y n el cardinal (longitud) del alfabeto de entrada. Como clave se puede utilizar cualquier palabra de una longitud por ejemplo entre 6 y 8 caracteres, que no tenga letras repetidas. Para ver mejor esto, supongamos que con nuestro alfabeto español de 27 símbolos, queremos cifrar el texto en claro "PLAN", y que para el cifrado utilizamos como clave la palabra "SOL". La primera letra del mensaje , la P se cifrará con la primera letra de la clave, S, lo que indica que tenemos que hacer la sustitución monoalfabeto E("P") = E(16) = (16 + 19) mod 27 = 8 = "I", ya que si A ocupa la posición 0, S ocupa la posición 19 en nuestro alfabeto. La letra L del mensaje se cifrará usando la letra O de la clave, y la letra A del mensaje se cifrará usando la letra L de la clave. Para la última letra del mensaje (N) volveremos a usar a primera letra de la clave (S). Por lo tanto tenemos como resultado: Mensaje P L A N Clave SOL S Cifrado I Z L F
Para facilitar las operaciones con este criptosistema, se dispone el llamado cuadro de Vigenère, que está formado por una matriz cuadrada de 27x27 en el caso de un alfabeto de 27 letras como el español. La primera fila de la matriz está formada por el alfabeto empezando por la letra A y acabando en la letra Z, la segunda por el alfabeto que empieza por la B y acaba en A, y así hasta la última fila, la 27ª, que empieza por las letras ZAB... y acaba con la letra Y.
Aplicación de ejemplo: El cifrado Vigenère Criptoanálisis del cifrado Vigenère
Para criptoanalizar este tipo de cifrado es necesario con efectuar d análisis estadísticos independientes agrupando los símbolos del criptograma en grupos distintos según la k i empleada para codificarlos; cada grupo estará codificado con el mismo alfabeto de cifrado. Para estimar la longitud d de la clave, (o sea, el número de alfabetos distintos empleados en el cifrado) buscaremos la periodicidad de los patrones comunes que puedan aparecer en el texto cifrado. Obviamente, para el criptoanálisis, necesitaremos al menos d veces más cantidad de texto cifrado que con los métodos monoalfabéticos.
Criptosistemas de clave pública. El cifrado RSA
Criptosistemas de clave pública Como ya se ha visto en el apartado de introducción a la criptografía, los criptosistemas de clave pública (también llamados criptosistemas asimétricos) se caracterizan por utilizar claves distintas para el cifrado y descifrado de la información. Su principal ventaja es que facilitan el proceso de distribución e intercambio de claves entre los participantes de la comunicación segura, que era un problema importante de los criptosistemas simétricos o de clave privada. Los algoritmos asimétricos emplean generalmente longitudes de clave mucho mayores que los simétricos, que usan una única clave secreta. Por ejemplo, mientras que para algoritmos simétricos se considera segura una clave de 128 bits, para la mayoría de algoritmos asimétricos (incluido el del RSA), se recomiendan actualmente claves de al menos 1024 bits de longitud. Además, la complejidad de cálculo que comportan los algoritmos de los criptosistemas asimétricos los hace considerablemente más lentos que los algoritmos de cifrado simétricos. Por eso en la práctica los métodos asimétricos se emplean principalmente para codificar la clave de sesión (simétrica) de cada comunicación o transacción particular. La criptografía basada en criptosistemas de clave pública es relativamente reciente, pues los primeros algoritmos asimétricos aparecen después de 1975. El criptosistema de esta clase más importante y extendido hoy en dia es el RSA, que utiliza la exponenciación modular para cifrar y descifrar y basa su seguridad en la complejidad del problema de la factorización de enteros grandes.
El criptosistema RSA De entre todos los algoritmos asimétricos, RSA es el más usado y también quizás el más sencillo de entender e implementar. Una peculiaridad de este algoritmo es que sus dos claves sirven indistintamente tanto para cifrar como para autenticar. Debe su nombre a sus tres inventores: Ronald Rivest, Adi Shamir y Leonard Adleman, que publicaron por primera vez el método RSA en 1977. Ha estado bajo patente de los Laboratorios RSA hasta el 20 de septiembre de 2000, por lo que su uso comercial estuvo restringido hasta esa fecha.
RSA, como ya se ha indicado, se basa en la difcultad que presenta la factorización de números grandes. Las claves pública y privada se calculan a partir de un número que se obtiene como producto de dos primos grandes. Un atacante que quiera recuperar un texto claro a partir del criptograma y de la clave pública, tiene que enfrentarse a dicho problema de factorización. El problema de la factorización de números grandes
Ya conocemos una forma posible de descomponer un número n en sus factores: probar a dividirlo por todos los números enteros positivos comprendidos entre 2 y la raíz de n. Pero cuando hablamos de un número de tamaño 1024 bits, este método es computacionalmente impracticable. Por supuesto, a lo largo del tiempo los matemáticos han inventado otros métodos de factorización más eficientes, pero ninguno ha conseguido un algoritmo con un orden de complejidad que permita factorizar en un tiempo razonable números de tamaños como los empleados en RSA actualmente, aun con la potencia computacional disponible hoy en día. De hecho el problema de la factorización de enteros se considera que es un problema de clase NP, es decir, un problema para el que existe uno o más algoritmos que lo resuelven, pero ninguno de los algoritmos conocidos se ejecutan en un tiempo polinomial (que pueda ser expresado polinómicamente en función del tamaño de los datos de entrada), y por lo tanto son ineficientes o intratables para datos de entrada muy grandes. El algoritmo RSA (1) Generación del par de claves
Para generar un par de claves (KP ; Kp), en primer lugar se eligen aleatoriamente dos números primos grandes, p y q (de unas 200 cifras cada uno, por ejemplo). Después se calcula el producto n = p.q Escogeremos ahora un número e primo relativo con (p-1) y con (q-1). Este par de números (e,n) pueden ser conocidos por cualquiera, y constituyen la llamada clave pública e por tanto debe tener un inverso módulo (p-1)(q-1), al que llamamos d. Por supuesto se cumple que ed ≡ 1 mod((p-1)(q-1)), que es lo mismo que decir que ed = 1+k (p-1)(q-1) para algún entero k. La clave
privada será el par (d,n). Este número d debe mantenerse secreto y sólo será conocido por el propietario del par de claves. (2) Cifrado del mensaje con la clave pública
Hay que hacer notar que con este algoritmo los mensajes que se cifran y descifran son números enteros de tamaño menor que n, no letras sueltas como en el caso de los cifrados César o Vigènere. Para obtener el mensaje cifrado C a partir del mensaje en claro M, se realiza la siguiente operación: e C= M (mod n) (3) Descifrado del mensaje con la clave privada
Para recuperar el mensaje original a partir del cifrado se realiza la siguiente operación: d M= C (mod n) Justificación del método
Cd (mod n)= (Me)d (mod n) = M1+k(p-1)(q-1)(mod n) = (M(p-1)(q-1))k.M (mod n) [i] Si recordamos, la función de Euler φ(n)= (p-1)(q-1), y que en general, salvo azar improbable, se tendrá que mcd(M,p)=mcd(M,q)=mcd(M,n)=1. Y por tanto según el teorema de Euler-Fermat, Mφ(n) ≡ 1 (mod n) ⇒ (M(p-1)(q-1))k ≡ 1 (mod n) [ii] De [i] y [ii] se obtiene que C d (mod n) = 1.M (mod n) = M, para 0 < M
Por las propiedades de la exponenciación modular, el cifrado y descifrado son conmutativos: M = (Me mod n)d mod n = Md.e mod n = (Md mod n)e mod n = M Esto supone que si cifrando M con la clave pública e y a continuación descifrando el resultado con la privada d obtenemos de nuevo M, también podemos cifrar M con la clave privada d y descifrar el resultado con la clave pública e, volviendo a obtener M.
Esta propiedad es importante porque nos permite utilizar RSA no sólo para cifrar un mensaje, sino también para autenticar el mensaje, como veremos en el tema siguiente. Criptoanálisis del RSA
Para romper un cifrado RSA, podemos probar varias vías. Aparte de factorizar n, que ya sabemos que es un problema computacionalemente intratable en un tiempo razonable, podríamos intentar calcular φ(n) directamente, o probar por un ataque de fuerza bruta tratando de encontrar la clave privada d, probando sistemáticamente con cada uno de los números posibles del espacio de claves. Ambos ataques son, para n grandes, incluso aún más costosos computacionalmente que la propia factorización de n.
El uso de RSA en la seguridad de la información El criptosistema RSA permite no sólo garantizar la confidencialidad de la comunicación entre dos partes, cifrando en origen el mensaje que se va a transmitir por un canal inseguro y descifrándolo en recepción, sino que también proporciona otros servicios o funciones de seguridad de la información, como son la autenticación de origen , la integridad o el norepudio (mediante la firma digital). Veamos cómo se emplearía RSA para garantizar estos servicios. En una comunicación entre dos partes A y B, cada una de ellas generará antes de empezar su propio par de claves (pública, privada). Así A tendrá el par (KPA,kpA) y B su par (KPB,kpB), donde KP son las claves públicas que son conocidas por las dos partes, y kp las privadas, que cada parte guarda la suya en secreto y no será conocida por la otra parte. Recordar que KPA=(eA,nA) y kpA=(dA,nA). Lo mismo para el par de claves de B. CIFRADO
Suponemos que A quiere enviar un mensaje M confidencialmente a B a través de un medio de transmisión inseguro. Estos son los pasos que tiene que seguir: 1. Obtiene la clave pública del destinatario B, (eB,nB)
2. Representa el texto en claro que quiere transmitir como un entero positivo M < n 3. Computa el mensaje cifrado: C = (M)eB mod nB 4. Finalmente transmite el criptomensaje C por el canal inseguro DESCIFRADO
Cuando B reciba el mensaje cifrado C, hace lo siguiente: 1. Usa su clave privada (dB, nB) para computar M = (C)dB mod nB 2. Recupera el texto original a partir de su entero representante M
FIRMA DIGITAL
Supongamos que A quiere enviar un mensaje a B. Este mensaje puede ir cifrado o no, pero A está interesado en "firmar" el mensaje de forma que B pueda estar seguro que el mensaje que le llega ha sido originado por A y no por ninguna otra entidad. Los pasos que A seguirá son: 1. Crea un resumen (digest) del mensaje que quiere enviar, utilizando una función hash 2. Representa este resumen como un entero M entre 0 y n-1
3. Usa su propia clave privada (dA,nA) para computar la firma S= (M)dA mod nA 4. Envía esa firma S al receptor B conjuntamente con el mensaje original (que puede ir cifrado o no, según se quiera). Evidentemente, la firma S no podrá ser manipulada por nadie una vez generada, porque si se cambia un sólo bit de la firma fallaría la verificación de ésta en destino. VERIFICACIÓN DE FIRMA DIGITAL
Cuando B recibe la firma S y el mensaje de A, sigue estos pasos: 1. Utiliza la clave publica del remitente A para computar V = (S)eA mod nA 2. Del entero V obtiene el resumen r del mensaje tal y como fue computado por A 3. Paralelamente, computa un resumen r' del mensaje que le ha llegado utilizando la función hash correspondiente 4. Si ambos resúmenes r y r' coinciden, entonces queda verificada la firma. Entonces puede asegurarse que el mensaje solo ha podido ser originado por A y además el mensaje ha llegado íntegramente (sin ver alterado su contenido durante la transmisión por el canal inseguro) hasta B.
Con la firma digital puede por tanto garantizarse la autenticación del origen, la integridad del mensaje y también el no-repudio en origen, puesto que si B ha podido recuperar el resumen r del mensaje utilizando la clave pública de A, la firma recibida junto con el mensaje sólo puede haber sido generada con la clave privada secreta de A.
Aplicación de ejemplo de cifrado RSA Funciones hash o resumen
Para la autenticación de mensajes largos, se utilizan las llamadas funciones hash o resumen. Estas funciones permiten obtener resúmenes (digests) de tamaño fijo a partir de diferentes mensajes muy largos, con la propiedad de que cada mensaje dará lugar a un resumen diferente al de los otros mensajes. De esta forma, en lugar de por ejemplo firmar mediante el algoritmo RSA un mensaje que puede ocupar varias páginas, lo que se firma (cifrándolo con la clave privada del emisor) es un número resumen del mensaje, que equivale al mensaje completo. Una función resumen r(m) para aplicarla a un mensaje m, ha de cumplir las siguientes propiedades: • •
r(m) es de longitud fija, independientemente de la longitud de m, y normalmente más pequeña que la longitud del mensaje. Dado m, es fácil calcular r(m).
•
Dado r(m), es computacionalmente intratable recuperar m. Por eso a las funciones hash también se las conoce como funciones unidireccionales. Su operación no es reversible.
•
Dado m, es computacionalmente intratable obtener otro mensaje m 0 tal que r(m) = r(m0). De esta forma, sabemos que para un valor r(m) solo puede corresponderle un m que lo haya generado.
En general, las funciones resumen se basan en funciones análogas a los algoritmos de compresión de información, que dan como resultado bloques de longitud n a partir de bloques de longitud mayor m. Ejemplos de funciones resumen usadas en criptografía son los algoritmos MD5, y el más seguro SHA-1 empleados ambos hoy en las firmas digitales.