domingo, 22 de octubre de 2017

Cifrado asimétrco

Introducción

Anteriormente se había hablado de Criptografía y algoritmos de cifrado simétrico. En esta ocasión el tema son los principales algoritmos de cifrado asimétrico.

En 1998 la Electronic Frontier Foundation (EFF) anunció que había roto un cifrado DES utilizando una máquina especializada "DES cracker". Poco después aparecieron otros algoritmos de clave privada como AES, triple DES e IDEA, sin embargo, la mayoría eran vulnerables y poco seguros.

Ante el problema de mantener en secreto el intercambio de claves secretas, aparecieron los cifrados de clave pública (asimétricos), que están basados en funciones matemáticas y no en simples operaciones sobre los patrones de bits.

Cifrado asimétrico


La criptografía asimétrica (también conocida como de clave pública) es un sistema que emplea una pareja de claves. Esta pareja de claves pertenecen a la misma persona. Una es de dominio público y cualquiera puede tenerla y la otra es privada.

El funcionamiento de este sistema es el siguiente: El remitente usa la clave pública del destinatario y sólo con la clave privada se podrá descifrar el mensaje. De esta forma se consigue que sólo el destinatario pueda acceder a la información. De la misma forma si el propietario usa su clave privada para cifrar un mensaje sólo se podrá descifrar con la clave pública. Usando la clave privada el propietario demuestra su identidad.

Sin embargo este sistema tiene varias desventajas:
  • Mayor tiempo de proceso en mismas condiciones respecto a clave simétrica.
  • Claves más grandes en en sistemas simétricos.
  • El mensaje cifrado es más grande que el original.

Por estas razones el principal uso del cifrado asimétrico es solventar los problemas a la hora de intercambiar las claves del cifrado simétrico.

Diffie - Hellman

En 1976 W. Diffie y M. Hellman publican el artículo New Directions in Cryptography donde establecen las bases de la criptografía pública. Introducen tres primitivas de clave pública:
1.- Esquemas de cifrado de clave pública.
2.- Esquemas de firma digital.
3.- Protocolos de intercambio de claves.

El protocolo de cifrado Diffie-Hellman es un sistema de intercambio de claves entre partes, que no han contactado previamente, a través de un canal inseguro y sin autenticación. Este protocolo se utiliza principalmente para intercambiar claves simétricas de forma segura para posteriormente pasar a utilizar un cifrado simétrico, menos costoso que el asimétrico. Se parte de la idea de que dos interlocutores pueden generar de forma conjunta una clave sin que esta sea comprometida.
  1. Se escoge un número primo p y un generador g que será coprimo de p. Estos 2 números son públicos.
  2. Escogemos un número a menor que p y calculamos A = g^a mod p. Enviamos A, p y g al otro interlocutor.
  3. El otro interlocutor escoge un número b menor que p y calcula B = g^b mod p. Nos envia B. 
Ahora, ambos podemos calcular K= g^(a-b) mod p. Para nosotros B^a mod p = K y para nuestro interlocutor A^b mod p =K. Usamos K como clave. 

Al ser p y g públicos cualquier atacante puede conocerlos. Esto no supone una vulnerabilidad. Aunque el atacante conociera estos dos número y capturase A y B, le resultaría computacionalmente imposible obtener a y/o b y consecuentemente K.


RSA

RSA (Rivest, Shamir y Adleman) es un algoritmo de cifrado asimétrico desarrollado en el año 1977.

Este algoritmo se basa en escoger 2 números primos grandes elegidos de forma aleatoria y mantenidos en secreto. 

La principal ventaja de este algoritmo desde el punto de vista de seguridad radica en la dificultad a la hora de factorizar números grandes. RSA es seguro hasta la fecha. 

El algoritmo funciona de la siguiente manera:

Tenemos un mensaje M. 
Empleando un protocolo reversible conocido como patrón de relleno convertimos el mensaje M en un número m menor que otro número dado n. 
Se genera el mensaje cifrado c:
c = m^e (mod n)
Se obtiene m descifrando el mensaje cifrado c:
m = c^d (mod n)

DSS

Diseñado para utilizar el algoritmo de firma SHA. DSS modifica el esquema de ElGamal para que mensajes de 160 bits puedan firmarse con 320 bits, pero realizando la computación módulo 512. DSS trabaja con un subgrupo de Z ∗ p de talla 2160. 

La seguridad se fundamenta en la creencia de que el problema del logaritmo discreto conserva sus propiedades en dicho subgrupo 

Funciona de la siguiente manera:

  1. Seleccionar q primo tal que 2^159 < q < 2^160.
  2. Sea 0 ≤ t ≤ 8, escoger p primo ( 2^(511+64t) < p < 2^(512+64t) ) tal que q divide (p − 1).
  3. Seleccionar α, generador del único grupo de orden q en Z∗p.
  4. Denotamos el resumen del mensaje con x′.
  5. Sea a un número aleatorio y β = α^a (mod p)
          k = (p, q, α, β, a); kpb = (p, q, α, β); kpr = (a)
  • Generar aleatoriamente h tal que 0 < h < q 
        sigk (x′ , h) = (γ, δ) 
        donde:

    • γ = (α h mod p) mod q 
    • δ = (x ′ − aγ)h −1 mod q
  • verk (γ, δ) = cierto si y sólo si α^h mod p ≡ α^((δ ^−1)(x′)) β^((δ^−1)(γ)) mod p (mod q)

Curva Elíptica


La teoría de curvas elípticas sobre cuerpos finitos encuentra aplicaciones en diversas disciplinas, como por ejemplo la teoría de números o la criptografía. 

En el campo de la criptografía, la aplicación de estas curvas la podemos encontrar en la descomposición de un número en factores, en los sistemas criptográficos y en los tests de primalidad, estos últimos desarrollados por Bosma, Goldwasser-Killian, Atkin y Lenstra entre otros.

Los criptosistemas de curva elíptica (ECC) fueron inventados por Neal Koblitz y Victor Miller in 1985.

Funcionan de la siguiente manera:
  • Generación de claves:

    1. Se establece un primo p y una curva elíptica y^2 = x^3 + ax + b sobre Zp. 
    2. Se establece un elemento G de la curva, de orden primo q de longitud similar a p. 
    3. Se elige aleatoriamente un entero d ∈ [0, q − 1] y se calcula P = dG. 
    4. La clave pública es P y los valores (a, b, q, G) son todos públicos. 
    5. La clave privada es d. 
Nótese que sobre el entero d no hay más restricción que el rango [0,q-1], al contrario que en RSA, que debía de ser primo. Este es principalmente el motivo por el cual la generación de claves es más rápida en curvas elípticas.

  • Intercambio de claves (ECDH): Elliptic curve Diffie–Hellman es un protocolo de intercambio de claves que permite a dos individuos que disponen de una clave pública y otra privada, establecer un secreto compartido. Este secreto puede ser directamente usado como clave o para derivar una clave. En particular, es una variante del protocolo Diffie–Hellman (DH) usando curvas elípticas. Los pasos son: 
    1. Tanto el emisor A como el receptor B acuerdan una curva elíptica E sobre un cuerpo finito Zp suficientemente segura y acuerdan un punto G ∈ E(Zp) tal que el subgrupo generado por G sea de un orden grande. 
    2. A elige un entero aleatorio a y envía PA = aG. 
    3. B elige un entero aleatorio b y envía PB = bG
    4. A calcula aPB = abG
    5. B calcula bPA = abG.
    6. Finalmente se tiene que la coordenada x de abG es el secreto compartido.
La seguridad de este secreto radica en la dificultad de resolver el problema del logaritmo discreto, es decir, conociendo G, aG y bG ∈ E(Zp), calcular abG. Para ello, p debe ser suficientemente grande.
  •  Cifrado y descifrado:
ECIES (Elliptic curve integration scheme) fue creado por Bellare y Rogaway y propuesto como estándar por Victor Shoup en el año 2001. ECIES combina un mecanismo de encapsulación de la clave (KEM) con un mecanismo de encapsulación de los datos (DEM). El sistema saca por separado una clave para cifrar y una clave MAC a partir de un secreto compartido. Primero, los datos se encriptan sim´etricamente, y después el texto cifrado se autentica con el MAC. Por último, el secreto común se encripta usando el par de claves pública/privada. La salida de la función de cifrado es la tupla {K, C, T}, donde K es el secreto compartido cifrado, C es el texto cifrado y T es la etiqueta de autenticaci´on. 

Por tanto, ECIES necesita dos funciones hash H1, H2 y una función de cifrado simétrico Ek (dependiente de la clave k).

Funciona de la siguiente manera:
  1. A elige un entero aleatorio k, 1 ≤ k ≤ N − 1, donde N es el orden del punto G que mencionamos anteriormente.
  2. A calcula R = kG y Z = kKpubB. 
  3. A escribe la salida de H1(R, Z) como dos cadenas k1, k2 concatenadas de longitudes espeíıficas. 
  4. A calcula C = Ek1 (m) y t = H2(C, k2). 
  5. A envía el texto cifrado (R, C, t) a B. 
Y para descifrar, B deberá hacer: 
  1. B calcula Z = KprivBR. 
  2. B calcula H1(R, Z) y escribe la salida como k1||k2. 
  3. B calcula H2(C, k2). Si no es igual a t, B para y rechaza el descifrado. Y si es igual a t, continúa. 
  4. B calcula m = Dk1 (C), donde Dk1 es la función de descifrado para Ek1. 

Conclusiones

Hoy en día, es imposible asegurar la invulnerabilidad de cualquier algoritmo, pero mediante la implementación de más de uno es posible mantener nuestros sistemas libres de ataques y por tanto lograr el mayor grado de seguridad.
Lo ideal, como ya se mencionó, es utilizar un algoritmo de clave pública para el intercambio de la clave privada de un algoritmo simétrico, de esta manera el sistema de cifrado será eficiente y el intercambio de la clave estará protegido.
Como sea, es importante recalcar que a cada momento se dan avances en el campo de la criptografía y el criptoanálisis y por esto mismo hay que estar actualizados en cuanto a los mecanismos de cifrado que se consideran seguros en la actualidad.

Referencias
  • UNAM. (Octubre 22, 2017). Definiciones e historia de la seguridad informática . Obtenido de http://www.ptolomeo.unam.mx:8080/jspui/bitstream/132.248.52.100/217/4/A4.pdf
  • Stallings, W. (2004). Fundamentos de Seguridad en Redes: Aplicaciones y Estándares. España: PEARSON EDUCACIÓN, S.A.
  • Luna, C. y Morrillo, P. (2009) Aplicaciones de las curvas elípticas a la criptografía. (Octubre 22, 2017). Obtenido de: http://divulgamat2.ehu.es/divulgamat15/index.php?option=com_content&task=view&id=9874&Itemid=67&showall=1
  • Matheu, S. (2015). Trabajo de fin de grado. Octubre 22, 2017, de Universidad de Murcia. Sitio web: http://www.um.es/documents/118351/1884002/TFG_MATHEU+GARCIA.pdf/0f3f6eb9-5ef7-4483-b41f-525bf7ef1160

viernes, 13 de octubre de 2017

Sockets

Sockets

Introducción

En 1977 la Organización Internacional de Estandarización (Internacional Standards Organization, ISO) estableció un subcomité encargado de diseñar una arquitectura de comunicación y el resultado fue el modelo de referencia para la Interconexión de Sistemas Abiertos OSI (Open Systems Interconection), el cual define una arquitectura de comunicación estructurada en siete niveles.

Existen dos protocolos fundamentales en el nivel de transporte de la arquitectura de red: el protocolo de datagrama de usuario (UDP, User Datagram Protocol) y el protocolo de control de transmisión (TCP, Transmission Control Protocol).

TCP está orientado a conexión y transporta un flujo de datos sobre una conexión lógica establecida entre el emisor y el receptor, mientras que UDP permite que un paquete se transporte utilizando comunicaciones sin conexión.

La Interfaz Socket es una API para redes TCP/IP que se compone de funciones o rutinas. Originalmente se construyó a principios de los 80 para el sistema operativo UNIX , aunque hoy en día también la utilizan otros sistemas operativos como Microsoft Windows, Mac, OS2, etc.

El API de sockets de Java, como el resto de interfaces de programación de sockets, proporciona construcciones de programación de sockets que hacen uso tanto del protocolo UDP como TCP.

Sockets

Los sockets son la interfaz más difundida que hay para la comunicación de procesos. Socket designa un concepto abstracto por el cual dos programas pueden intercambiarse cualquier flujo de datos, el socket no es más que un "canal de comunicación" entre dos programas que corren sobre ordenadores distintos o incluso en el mismo ordenador.

Un socket se caracteriza por tres atributos:

  • Dominio: Especifica el medio de comunicación de la red que el socket utilizará.
  • Protocolo: Especifica qué protocolo se va a usar.
  • Tipo: Los protocolos de internet proveen dos niveles distintos de servicio : flujo y datagramas.
  • ¿Qué define a un socket?

    Para que dos programas puedan comunicarse entre sí es necesario que un programa sea capaz de localizar al otro, y además, que ambos programas sean capaces de intercambiarse cualquier secuencia de octetos, para ello son necesarios los tres recursos que originan el concepto de socket, y gracias a los cuales éste queda definido:

  • Un protocolo de comunicaciones, que permite el intercambio de octetos.
  • Una dirección del Protocolo de Red, que identifica una computadora.
  • Un número de puerto, que identifica a un programa dentro de una computadora.
  • Tipos de Sockets

    Sockets Stream: Son los más utilizados, hacen uso del protocolo TCP, el cual nos provee un flujo de datos bidireccional, secuenciado, sin duplicación de paquetes y libre de errores.

    Sockets Datagram: Hacen uso del protocolo UDP, el cual nos provee un flujo de datos bidireccional, pero los paquetes pueden llegar fuera de secuencia, pueden no llegar o contener errores. Por lo tanto el proceso que recibe los datos debe comprobar la secuencia, eliminar duplicados y asegurar la integridad. Se llaman también “sockets sin conexión”, porque no hay que mantener una conexión activa, como en el caso de sockets stream. Son utilizados para transferencia de información paquete por paquete.

    ¿Cómo se da la comunicación?

    Las aplicaciones desarrolladas en Sockets están basadas en la arquitectura Cliente-Servidor.

    Normalmente, un servidor se ejecuta en una máquina específica y tiene un socket asociado a un número de puerto específico. El servidor simplemente espera a la escucha en el socket a que un cliente se conecte con una petición. El cliente conoce el nombre de la máquina sobre la que está ejecutándose el servidor y el número de puerto al que está conectado. Solicitar una conexión consiste en intentar establecer una cita con el servidor en el puerto de la máquina servidora.

    Si todo va bien, el servidor acepta la conexión, pero antes crea un nuevo socket en un puerto diferente. Es necesario crear un nuevo socket (y consecuentemente un número de puerto diferente) de forma que en el socket original se continúe a la escucha de las peticiones de nuevos clientes mientras se atiende a las necesidades del cliente conectado.

    En el cliente, si se acepta la conexión, el socket se crea satisfactoriamente y se puede utilizar para comunicarse con el servidor.

    ¿Cómo se utilizan los sockets?

    En Java, el API de sockets datagrama proporciona dos clases:

    1. La clase DatagramSocket para los sockets.
    2. La clase DatagramPacket para los datagramas intercambiados.

    Proceso emisor:

    Un proceso que quiera mandar o recibir datos utilizando esta API debe instanciar un objeto DatagramSocket, o un socket para abreviar.

    Para mandar un datagrama a otro proceso, un proceso debe crear un objeto que representa el datagrama en sí mismo. Este objeto puede crearse instanciando un objeto DatagramPacket que englobe (1) una referencia a un vector de octetos que contenga los datos de la carga, y (2) la dirección de destino (el ID de la máquina y el número de puerto al que el socket del receptor está enlazado). Una vez que se crea el objeto DatagramPacket y en él se incluyen los datos de la carga y del destino, el proceso emisor realiza una llamada al método send del objeto DatagramSocket, especificando una referencia al objeto DatagramPacket como argumento.


    Proceso receptor:

    En el proceso receptor, también se debe instanciar un objeto DatagramSocket y enlazarlo a un puerto local; el número de puerto debe coincidir con el especificado en el paquete datagrama del emisor. Para recibir los datagramas enviados al socket, el proceso crea un objeto DatagramPacket que hace referencia a un vector de octetos y llama a un método receive de su objeto DatagramSocket, especificando como argumento una referencia al objeto DatagramPacket

    DatagramSocket

    Se trata de un servicio de transporte sin conexión. Son más eficientes que TCP, pero no está garantizada la fiabilidad: los datos se envían y reciben en paquetes, cuya entrega no está garantizada; los paquetes pueden ser duplicados, perdidos o llegar en un orden diferente al que se envió.

    El protocolo de comunicaciones con datagramas UDP, es un protocolo sin conexión, es decir, cada vez que se envíen datagramas es necesario enviar el descriptor del socket local y la dirección del socket que debe recibir el datagrama. Como se puede ver, hay que enviar datos adicionales cada vez que se realice una comunicación.

    public class java.net.DatagramSocket extends java.lang.Object
    1. Constructores:
      • public DatagramSocket () throws SocketException.
        Se encarga de construir un socket para datagramas y de conectarlo al primer puerto disponible.
      • public DatagramSocket (int port) throws SocketException.
        Ídem, pero con la salvedad de que permite especificar el número de puerto asociado.
      • public DatagramSocket (int port, InetAddress ip) throws SocketException.
        Permite especificar, además del puerto, la dirección local a la que se va a asociar el socket.
    2. Métodos:
      • public void close().
        Cierra el socket.
      • protected void finalize().
        Asegura el cierre del socket si no existen más referencias al mismo.
      • public int getLocalPort().
        Retorna el número de puerto en el host local al que está conectado el socket.
      • public void receive (DatagramPacket p) throws IOException.
        Recibe un DatagramPacket del socket, y llena el búfer con los datos que recibe.
      • public void send (DatagramPacket p) throws IOException.
        Envía un DatagramPacket a través del socket.

    DatagramPacket

    Un DatagramSocket envía y recibe los paquetes y un DatagramPacket contiene la información relevante. Cuando se desea recibir un datagrama, éste deberá almacenarse bien en un búfer o un array de bytes. Y cuando preparamos un datagrama para ser enviado, el DatagramPacket no sólo debe tener la información, sino que además debe tener la dirección IP y el puerto de destino, que puede coincidir con un puerto TCP.

    public final class java.net.DatagramPacket extends java.lang.Object
    1. Constructores:
      • public DatagramPacket(byte ibuf[], int ilength).
        Implementa un DatagramPacket para la recepción de paquetes de longitud ilength, siendo el valor de este parámetro menor o igual que ibuf.length.
      • public DatagramPacket(byte ibuf[], int ilength, InetAddress iaddr, int iport).
        Implementa un DatagramPacket para el envío de paquetes de longitud ilength al número de puerto especificado en el parámetro iport, del host especificado en la dirección de destino que se le pasa por medio del parámetro iaddr.
    2. Métodos:
      • public InetAddress getAddress ().
        Retorna la dirección IP del host al cual se le envía el datagrama o del que el datagrama se recibió.
      • public byte[] getData().
        Retorna los datos a recibir o a enviar.
      • public int getLength().
        Retorna la longitud de los datos a enviar o a recibir.
      • public int getPort().
        Retorna el número de puerto de la máquina remota a la que se le va a enviar el datagrama o del que se recibió.

    Conclusión

    Los sockets constituyen una herramienta extremadamente útil para la comunicación en un sistema distribuido, ya que su implementación es sencilla y eficiente. Sin embargo, el tipo de socket más utilizado actualmente es el orientado a conexión, ya que presenta mayores ventajas de seguridad e integridad de la información.

    En el futuro, la manera de comunicar un sistema distribuido probablemente se volverá cada vez más eficiente y sencilla, dejando a los sockets no orientados a conexión obsoletos.

    Referencias

  • Hoyo, J. L. (2017). TELECONTROL DE CÁMARA IP MEDIANTE SENSORES INALÁMBRICOS BLUETOOTH. Octubre 15, 2017, de Universidad de Sevilla Sitio web: http://bibing.us.es/proyectos/abreproy/11823/direccion/Volumen+I%252F
  • Liu, M. L. (2004). Computación Distribuida: Fundamentos y Aplicaciones. Madrid: PEARSON EDUCACIÓN, S.A.
  • Coulouris, G. (2001). Sistemas Distribuidos: conceptos y diseño. España: Pearson Educación.
  • Sistemas Heredados

    Conclusiones Los sistemas heredados pueden llegar a representar la base de la funcionalidad de una empresa, además de contener informa...