Está en la página 1de 28

UNIVERSIDAD TCNICA PARTICULAR DE LOJA

La Universidad Catlica de Loja

ESCUELA DE ELECTRNICA Y TELECOMUNICACIONES


PROYECTO DE SEGURIDAD DE REDES
Fecha: Paralelo: Integrantes: 2013-07-10. 8vo B. -Eduardo Israel Brito Vivanco. -Eduardo Luis Campoverde Encalada.

APLICACIN DE CHAT SEGURO EN JAVA-ECLIPSE

Figura 1: Esquema de conexin para chat de mensajera entre dos equipos.

1. Introduccin: La violacin a la seguridad de las redes ha sido a lo largo de los aos un gran inconveniente para los usuarios de la red como para los administradores de la misma; es por ello, que stos ltimos han centrado sus estudios para conservar la confidencialidad, la integridad y la disponibilidad de los datos que se envan entre un emisor y un receptor como servicios fundamentales dentro del mbito de la seguridad de las redes. La seguridad en los datos sobre una red es de suma importancia debido a que la informacin que se enva en la mayora de los casos se requiere que solo est disponible para cierta persona o grupo de personas, es por ello que la encriptacin en los mensajes enviados da solucin a este problema mediante el cifrado con claves que nicamente el origen de los datos o el destino conocen. Para dicha encriptacin, se puede emplear un cifrado simtrico en el que los datos se cifran y descifran con la misma clave que tanto el emisor como el receptor conocen, o un

cifrado asimtrico en el que tanto el origen como el destino tienen una clave pblica y una clave privada; la clave pblica es conocida por todos y mediante esta clave se cifran los mensajes que nicamente el dueo de la clave privada podr leer asegurando con ello que l y nicamente l podr acceder a la informacin enviada por el emisor. 2. Objetivos 2.1. Objetivo General: Crear una aplicacin de mensajera segura mediante el software Java-Ecplise.

2.2. Objetivos Especficos: 2.2.1. Objetivos relacionados con mensajera en texto claro: Generar una conexin entre el equipo A y B y enviar mensajes sin cifrar entre los dos equipos. Capturar el trfico enviado entre A y B, y validar que se pueden ver los mensajes en texto claro mediante el software Wireshark.

2.2.2. Objetivos relacionados con mensajera cifrada: Generar llaves privadas, llaves pblicas y certificados digitales autofirmados para el Equipo A y el Equipos B mediante la herramienta Keytool. Crear los almacenes KeyStore tanto para el cliente como para el servidor en el que se almacenan las claves privadas con los certificados asociados tanto del cliente como del servidor. Crear un almacn TrustStore en el que se almacenan las llaves pblicas correspondientes a cada uno de ellos. Encriptar los mensajes entre el Equipo A y el Equipo B empleando seguridad SSL implementada en la capa de aplicacin en el software Eclipse. Capturar el trfico entre los equipos y validar que ste se encuentre encriptado.

3. Resultados: 3.1. Mensajera sin cifrar (texto en claro): La aplicacin realizada en el software Eclipse est conformada de dos partes: la primera correspondiente al servidor que proporciona el servicio de chat para el envo continuo de

mensajes entre el cliente y el servidor, y la segunda que hace referencia al cliente que usa la aplicacin creada por el servidor para el chat entre los dos. 3.1.1. Servidor: Al compilarse el programa server, el servidor levanta el Socket del Servidor en el puerto 10000 para poder recibir una peticin del cliente y posteriormente establecerse una comunnicacin full duplex con ste. Al ejecutarse server, inicialmente aparece una interfaz donde se introduce el nombre del usuario que sirve de identificador para mostrarse durante el servicio de chat. Para este caso el nombre que se a introduciodo como identificador del server es eduardce.

Figura 2: Entrada del nombre de usuario para el servicio de chat.

Una vez ingresado el nombre de usuario, el puerto del Socket del servidor se encuentra en estado de escucha a la espera de la conexin del cliente tal como se observe a continuacin:

Figura 3: Estado de escucha del equipo servidor en el puerto 10000.

Figura 4: Estado de espera por parte del servidor a que el cliente se conecte.

Una vez que el cliente se conecta al server, tal situacin se observa en la interfaz de chat del server, donde se puede visualizar la ip que el cliente dispone:

Figura 5: Conexin establecida con el cliente.

Realizado ello, se puede utilizar el servicio de chat implementado en eclipse, donde gracias al identificador de usuario que tanto server como cliente disponen, se puede identificar fcilmente quien es el emisor de cada mensaje. A continuacin se observa que en la ventana del server con identificador eduardce se est presto a enviar el mensaje: mas o menos.

Figura 6: Envo de mensajes entre el cliente y el servidor.

3.1.2. Cliente: En la figura 7, figura 8 y figura 9 se muestra la solicitud de comunicacin por parte del cliente al servidor. En la figura 7 se puede observar que el cliente ingresa su nombre que es con el cual aparecer en la ventana del chat una vez establecida la comunicacin. Para este trabajo se ha asignado como nombre de cliente EduardoBrito.

Figura 7: Entrada del nombre de usuario para el servicio de chat.

En la figura mostrada a continuacin (figura 8) se indica la direccin IP del servidor al que el cliente se quiere conectar, en este caso se puede observar que la direccin del servidor es 192.168.1.1.

Figura 8: Ingreso de la direccin IP del servidor de chat.

A continuacin se puede observar que el cliente tambin debe elegir el puerto a emplear en la aplicacin de chat establecida por el servidor, para este caso se puede ver en la figura 9 que el puerto seteado es el puerto 10000.

Figura 9: Ingreso del nmero de puerto usado por la aplicacin de chat.

Con los pasos nombrados anteriormente la comunicacin entre el servidor y el cliente se encuentra establecida, tal como se muestra en la figura 10, y se puede empezar a utilizar la aplicacin de chat desarrollada en java.

Figura 10: Conexin establecida con el servidor.

En la figura 11 se puede observar como se est realizando el envo de mensajes por parte del cliente que para ste caso tiene el nombre EduardoBrito y tambin como se est recibiendo mensajes provenientes del servidor que ha iniciado sesin con el nombre eduardce.

Figura 11: Mensajes enviados entre el cliente y el servidor.

3.1.3. Capturas en Wireshark: A travs del software Wireshark, se captur la comunicacin full dplex establecida entre cliente y server, visualizndose los mensajes intercambiados entre ambos. Adems, se verific que dicha informacin enviada viaja en forma de texto plano, pues se puede visualizar todos los mensajes que se setearon mientras se chate. A continuacin se presenta la informacin intercambiada entre cliente y el server capturada en Wireshark:

Paquetes en formato hexadecimal

Paquetes en texto claro

Figura 12: Captura de los mensajes enviados entre el cliente y el servidor.

Como se observa en la imagen anterior, se tiene el texto capturado tanto en formato hexadecimal como en texto plano, donde el cdigo hexadecimal es el formato en que los paquetes son transportados, mientras el texto plano es el formato en el que aparecen los mensajes en la capa de aplicacin que para este caso corresponde a la interfaz del chat. En la interfaz inferior de Wireshark, se puede observar el mensaje con el que se inici el de servicio de chat, mismo que fue enviado por parte del cliente Eduardo Brito con ip 192.168.1.2: hola, tanto en texto en claro como en formato hexadecimal.

Figura 13: Captura del primer mensaje enviado por EduardoBrito.

En la imagen siguiente se puede observar que en la interfaz inferior de Wireshark aparece el mensaje que el servidor eduardce con direccin ip 192.168.1.1 enva: mas o menos, tanto en texto claro como en formato hexadecimal.

Figura 14: Captura de uno de los mensajes enviados por eduardce.

3.2. Mensajera cifrada (texto encriptado): Primeramente, mediante la herramienta KeyTool, se han generado las claves pblicas y privadas tanto para el servidor como para el cliente y se han almacenado la clave privada y el certificado asociado tanto para el servidor como para el cliente en un almacn KeyStore; adems de ello se ha generado un almacn TrustStore que contiene las claves pblicas tanto del cliente como del servidor y que es compartido por ambos. La aplicacin realizada en el software Eclipse es la misma que se emple en la mensajera sin cifrar (texto en claro) con la diferencia de que se aadi la seguridad SSL en la capa de aplicacin, es decir, que el software ser el encargado de emplear el protocolo SSL para encriptar (criptografa simtrica) los mensajes con la clave de sesin que se intercambia previamente entre el cliente y el servidor mediante el uso de una criptografa asimtrica con las claves pblicas y privadas correspondientes a cada uno de ellos. A continuacin se presentan los resultados obtenidos con la mensajera de texto encriptado: 3.2.1. Capturas en Wireshark: Nuevamente, en Wireshark se captur la comunicacin full dplex establecida entre cliente y server, donde se observ que ahora los mensajes intercambiados entre ambos viajan encriptados, pues todos los textos que tanto el cliente como el servidor enviaron durante la sesin de chat, aparecen en formato alfanumrico ilegible. A continuacin se presenta la informacin encriptada intercambiada entre cliente y server capturada en Wireshark:

Figura 15: Captura del certificado enviado por el servidor Eduardo Campoverde.

Como se observa en la imagen anterior, antes de enviarse la informacin cifrada el server se autentica ante el cliente a travs del envo de su certificado. Este certificado contiene entre otras partes la autoridad de autentificacin que al tratarse del server es Eduardo Campoverde, el propietario del certificado que al ser auto-firmado es igual Eduardo Campoverde, el nombre de la unidad de organizacin UTPL, la organizacin Seguridadredes, la localidad Loja al igual que la provincia, as como la clave pblica del propietario.

Figura 16: Captura del certificado enviado por el cliente Eduardo Brito.

AL igual que el server, el cliente antes de enviar la informacin cifrada se autentica ante el servidor cliente a travs del envo de su certificado. Este certificado contiene entre otras partes la autoridad de autentificacin que al tratarse del server es Eduardo Brito, el propietario del certificado que al ser auto-firmado es igual Eduardo Brito, el nombre de la unidad de organizacin UTPL, la organizacin Seguridadredes, la localidad Loja al igual que la provincia, as como la clave pblica del propietario. Al igual que se realiz para la captura del chat en texto claro se intercambi los mismo mensajes mostrados anteriormente, es as que en la interfaz inferior de Wireshark se puede observar el mensaje con el que se inici el de servicio de chat, mismo que fue enviado por parte del cliente Eduardo Brito con ip 192.168.1.2: hola, tanto en texto cifrado (cdigo alfanumrico) como en formato hexadecimal.

Figura 17: Captura de uno de los mensajes encriptados enviados por EduardoBrito.

La siguiente imagen hace referencia al mensaje que el servidor eduardce con direccin ip 192.168.1.1 enva: mas o menos, sin embargo lo que se observa es el texto enviado tanto en formato cifrado como en cdigo hexadecimal.

Figura 18: Captura de uno de los mensajes encriptados enviados por eduardce.

4. Conclusiones: Se implement un servicio de chat entre dos equipos mediante el uso del software JAVA-Eclipse tanto para la mensajera en texto claro como para la cifrada. Para establecer la aplicacin de chat, el equipo que desempea la funcin de servidor levanta el socket en un puerto seteado por el usuario para ponerlo a ste en estado de Listening a la espera de la conexin del cliente. Para que el cliente inicie la conexin con el servidor, el usuario ingresa la direccin IP del servidor y el puerto de escucha que ste ha levantado. Al capturar el trfico del intercambio de mensajes sin cifrar en Wireshark se observ que los mensajes se encuentran en texto claro y pueden ser ledos por cualquier persona que los capture. Para la comunicacin cifrada cliente-servidor se gener 5 archivos mediante la herramienta KeyTool: 2 almacenes KeyStore para las claves privadas y los certificados asociados tanto para el cliente como el servidor, 1 almacn compartido TrustStore para los certificados de claves pblicas de ambos y 2 certificados autofirmados X.509 correspondientes a cada usuario. Para la encriptacin en el envo de mensajes en la aplicacin chat se utiliz seguridad SSL implementada en la capa de aplicacin en el software Java-Eclipse.

Al capturar el trfico en Wireshark se observ que no se presentan las fases del protocolo HandShake de la seguridad SSL debido a que en ste caso SSL es implementado en la capa de aplicacin en Java-Eclipse por lo que este software es el que realiza de forma transparente a la capa de transporte las fases del protocolo HandShake. Al capturar los mensajes encriptados en Wireshark se observ que stos presentan un formato ilegible para cualquier persona por lo que no se puede visualizar el mensaje enviado originalmente. Tanto el servidor como el cliente se autenticaron entre ellos enviando sus certificados autofirmados para que puedan ser visualizados por la otra entidad. La seguridad SSL implementada en la capa de transporte resulta ser ms eficiente que la implementada en la capa de aplicacin pues requiere menor tiempo de procesamiento y brinda mayor seguridad a posibles ataques a la conexin.

5. Recomendaciones: Los certificados y almacenes generados para la mensajera encriptada se los puede crear en el sistema operativo Windows XP debido a que la informacin es ms fcil de encontrar en la Web que para otras versiones superiores de Windows. Los archivos generados mediante la herramienta KeyTool deben ser incorporados dentro del directorio donde se encuentra guardado el programa desarrollado en Java-Eclipse o caso contrario se los debe importar dentro desde ste a travs de la ruta de ubicacin de los mismos. Debe existir concordancia entre el puerto del Socket que levanta el servidor y el que es ingresado por el cliente.

ANEXOS
1. GENERACIN DE ALMACENES Y CERTIFICADOS EN KEYTOOL
Como pasos a seguir para generar tanto los almacenes como los certificados utilizados para establecer una conexin segura a travs de SSL, se debe primero abrir el smbolo del sistema y all en cmd seguir los siguientes pasos, mismos que estn detallados para el servidor: A. Generamos el par de claves pblica y secreta y se almacenan en el almacen AlmacenSR. keytool -genkey -alias Server -keyalg RSA -validity 1000" -keystore AlmacenSR keypass ooooo -storepass oooooo A partir de esta lnea de commando, nos aparece una serie de opciones de informacin del server que deben irse llenando: Cules son su nombre y su apellido? [Unknown]: Eduardo Campoverde Cul es el nombre de su unidad de organizacin? [Unknown]: UTPL Cul es el nombre de su organizacin? [Unknown]: Seguridadredes Cul es el nombre de su ciudad o localidad? [Unknown]: Loja Cul es el nombre de su estado o provincia? [Unknown]: Loja Cul es el cdigo de pas de dos letras de la unidad? [Unknown]: EC Es correcto CN=Eduardo Campoverde, OU=UTPL ,O=Seguridadredes, L=Loja, ST=Loja, C=EC? [no]: y Para visualizar la informacin que hemos seteado se usa el siguiente comando: keytool -list -v -keystore AlmacenSR B. Generamos en un fichero .cer el certificado de clave pblica. keytool -export -alias Server -keystore AlmacenSR -rfc -file CertServer.cer Luego de ejecutar esta lnea, debemos autorizar que se ejecute dicha sentencia colocando la clave del almacen AlmacenSR: Escriba la contrasea del almacn de claves: ooooo Certificado almacenado en el archivo <CertServer.cer> C. Metemos el certificado autofirmado en un almacn. keytool -import -alias Server -file CertServer.cer keystore AlmacenTrust

Realizados estos pasos, se traslada los tres estos archivos hacia el directorio donde se encuentre el programa del Server realizado en Java-Eclipse.

Figura 1: Archivos creados mediante la herramienta KeyTool.

Para el caso del cliente, se debe repetir los pasos antes citados con la diferencia de que se cambien el nombre de los almacenes, para este trabajo los almacenes para el cliente se los a denominado como AlmacenCL, AlmacenTrust (el mismo que se gener en server) y el CertCliente.cer. Igualmente, estos archivos deben ser adjuntados dentro del directorio donde se halla el programa cliente en Java-Eclipse.

2. Cdigo para generar una aplicacin de mensajera segura (SSL).


Dentro del servidor existen tres archivos desarrollados en Eclipse, el primero corresponde al programa principal del servidor mientras que los otros a las funciones de envo y recepcin de mensajes. Programa Principal Servidor

package servidor; import java.awt.BorderLayout; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.io.IOException; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.security.cert.X509Certificate; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.logging.Level; import java.util.logging.Logger;

import javax.net.ssl.*; import javax.swing.*; /**Clase que se encarga de correr los threads de enviar y recibir nick * y de crear la interfaz grafica. * * @author Rafa */ public class PrincipalChat extends JFrame{ public JTextField campoTexto; //Para mostrar mensajes de los usuarios public JTextArea areaTexto; //Para ingresar mensaje a enviar private static SSLServerSocket servidor; // private static SSLSocket conexion; //Socket para conectarse con el cliente //private static String ip = "127.0.0.1"; //ip a la cual se conecta public static PrincipalChat main; public String nick; public PrincipalChat(){ super("SERVIDOR"); //Establece titulo al Frame campoTexto = new JTextField(); //crea el campo para nick campoTexto.setEditable(false); //No permite que sea editable el campo de nick add(campoTexto, BorderLayout.SOUTH); //Coloca el campo de nick en la parte superior areaTexto = new JTextArea(); //Crear displayArea areaTexto.setEditable(false); add(new JScrollPane(areaTexto), BorderLayout.CENTER); areaTexto.setBackground(Color.lightGray); //Pone de color cyan al areaTexto areaTexto.setForeground(Color.BLACK); //pinta azul la letra en el areaTexto campoTexto.setForeground(Color.BLACK); //pinta toja la letra del mensaje a enviar

//Crea menu chat y submenu Salir, ademas agrega el submenu al menu JMenu menuArchivo = new JMenu("Servicio Chat"); JMenuItem salir = new JMenuItem("Salir"); menuArchivo.add(salir); //Agrega el submenu Salir al menu menuArchivo JMenuBar barra = new JMenuBar(); //Crea la barra de menus setJMenuBar(barra); //Agrega barra de menus a la aplicacion barra.add(menuArchivo); //agrega menuArchivo a la barra de menus //Accion que se realiza cuando se presiona el submenu Salir salir.addActionListener(new ActionListener() { //clase interna anonima public void actionPerformed(ActionEvent e) { System.exit(0); //Sale de la aplicacion } }); setSize(600,620); //Establecer tamano a ventana setVisible(true); //Pone visible la ventana

//Para mostrar nick en displayArea public void mostrarMensaje(String mensaje) { areaTexto.append(mensaje + "\n"); } public void habilitarTexto(boolean editable) { campoTexto.setEditable(editable); } //Metodo que permite obtener nombre de la persona public void ingresarNick(){ nick = JOptionPane.showInputDialog(null, "Nombre de Usuario "); }

/** * @param args the command line arguments */ public static void main(String[] args) { PrincipalChat main = new PrincipalChat(); //Instanciacion de la clase Principalchat main.setLocationRelativeTo(null); //Centrar el JFrame main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //habilita cerrar la ventana main.ingresarNick(); //llamada al metodo ingresarNick ExecutorService executor = Executors.newCachedThreadPool(); //Para correr los threads try { //main.mostrarMensaje("No se encuentra Servidor"); System.setProperty("javax.net.ssl.keyStore","C:/Users/JENNY ENCALADA/workspace/Proyecto_Chat/ChatSockets/AlmacenSR"); System.setProperty("javax.net.ssl.keyStorePassword","eduardce"); System.setProperty("javax.net.ssl.trustStore","C:/Users/JENNY ENCALADA/workspace/Proyecto_Chat/ChatSockets/AlmacenTrust"); SSLServerSocketFactory factory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); servidor = (SSLServerSocket) factory.createServerSocket(10000); servidor.setNeedClientAuth(true);

// servidor = (SSLServerSocket) new ServerSocket(11111); main.mostrarMensaje("Esperando Cliente..."); //Bucle infinito para esperar conexiones de los clientes while (true){ try {

conexion = (SSLSocket) servidor.accept(); SSLSession sesion = conexion.getSession(); System.out.println("Host: "+sesion.getPeerHost()); X509Certificate (X509Certificate)sesion.getPeerCertificates()[0]; certificate1 =

//Certificate certificate = sesion.getPeerCertificates()[0]; System.out.println("Propietario: "+certificate1.getSubjectDN()); System.out.println("Emisor: "+certificate1.getIssuerDN()); System.out.println("Numero Serie: "+certificate1.getSerialNumber() ); System.out.println("to string: "+certificate1.toString() );

System.out.println("**************************************************************** ******"); System.out.println("\n\n\n"); //conexion = servidor.accept(); //Permite al servidor aceptar conexiones //main.mostrarMensaje("Conexion Establecida"); main.mostrarMensaje("Conectado a conexion.getInetAddress().getHostName());

"

main.habilitarTexto(true); //permite escribir nick para enviar //Ejecucion de los threads executor.execute(new ThreadRecibe(conexion, main)); //client executor.execute(new ThreadEnvia(conexion, main)); } catch (IOException ex) { Logger.getLogger(PrincipalChat.class.getName()).log(Level.SEVERE, ex); } } } catch (IOException ex) { Logger.getLogger(PrincipalChat.class.getName()).log(Level.SEVERE, null, ex); } //Fin del catch finally { } executor.shutdown(); } } Funcin Enviar Mensajes

null,

package servidor; import java.io.IOException; import java.io.ObjectOutputStream; import java.net.Socket; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.net.SocketException; import javax.net.ssl.SSLSocket; public class ThreadEnvia implements Runnable { private final PrincipalChat main; private ObjectOutputStream salida; private String mensaje; private SSLSocket conexion; public ThreadEnvia(SSLSocket conexion, final PrincipalChat main){ this.conexion = conexion; this.main = main; //Evento que ocurre al escribir en el areaTexto main.campoTexto.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { mensaje = event.getActionCommand(); enviarDatos(mensaje); //se envia el mensaje main.campoTexto.setText(""); //borra el nick del enterfield } //Fin metodo actionPerformed } );//Fin llamada a addActionListener } //enviar objeto a cliente private void enviarDatos(String mensaje){ try { salida.writeObject(main.nick+">>> " + mensaje); // salida.writeObject("Servidor>>> " + mensaje); salida.flush(); //flush salida a cliente main.mostrarMensaje(main.nick+">> "+ mensaje); } //Fin try catch (IOException ioException){ main.mostrarMensaje("Error escribiendo Mensaje"); } //Fin catch } //Fin methodo enviarDatos //manipula areaPantalla en el hilo despachador de eventos public void mostrarMensaje(String mensaje) { main.areaTexto.append(mensaje); } public void run() {

try { salida = new ObjectOutputStream(conexion.getOutputStream()); salida.flush(); } catch (SocketException ex) { } catch (IOException ioException) { ioException.printStackTrace(); } catch (NullPointerException ex) { } } } Funcin Recibir mensajes

package servidor; import java.io.EOFException; import java.io.IOException; import java.io.ObjectInputStream; import java.net.Socket; import java.net.SocketException; import java.util.logging.Level; import java.util.logging.Logger; import javax.net.ssl.SSLSocket; public class ThreadRecibe implements Runnable { private final PrincipalChat main; private String mensaje; private ObjectInputStream entrada; private SSLSocket cliente;

//Inicializar chatServer y configurar GUI public ThreadRecibe(SSLSocket cliente, PrincipalChat main){ this.cliente = cliente; this.main = main; } public void mostrarMensaje(String mensaje) { main.areaTexto.append(mensaje); } public void run() { try { entrada = new ObjectInputStream(cliente.getInputStream()); } catch (IOException ex) { Logger.getLogger(ThreadRecibe.class.getName()).log(Level.SEVERE, null, ex); } do { //procesa los mensajes enviados dsd el servidor try {//leer el mensaje y mostrarlo mensaje = (String) entrada.readObject(); //leer nuevo mensaje

main.mostrarMensaje(mensaje); } //fin try catch (SocketException ex) { } catch (EOFException eofException) { main.mostrarMensaje("Fin de la conexion"); break; } //fin catch catch (IOException ex) { Logger.getLogger(ThreadRecibe.class.getName()).log(Level.SEVERE, null, ex); } catch (ClassNotFoundException classNotFoundException) { main.mostrarMensaje("Objeto desconocido"); } //fin catch } while (!mensaje.equals("Servidor>>> TERMINATE")); //Ejecuta hasta que el server escriba TERMINATE try { entrada.close(); //cierra input Stream cliente.close(); //cieraa Socket } //Fin try catch (IOException ioException) { ioException.printStackTrace(); } //fin catch main.mostrarMensaje("Fin de la conexion"); System.exit(0); } }

De igual forman, dentro del cliente existen tres archivos desarrollados en Eclipse, el primero corresponde al programa principal del cliente mientras que los otros a las funciones de envo y recepcin de mensajes. Programa Principal Cliente

package cliente; import java.security.cert.X509Certificate; import java.nio.charset.Charset; import java.util.Scanner; import java.awt.BorderLayout; import java.awt.Color; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.io.BufferedReader; import java.io.EOFException; import java.io.IOException;

import java.io.InputStreamReader; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.logging.Level; import java.util.logging.Logger; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import javax.swing.*; /**Clase que se encarga de correr los threads de enviar y recibir texto * y de crear la interfaz grafica. * * @author Rafa */ public class PrincipalChat extends JFrame{ public JTextField campoTexto; //Para mostrar mensajes de los usuarios public JTextArea areaTexto; //Para ingresar mensaje a enviar //private static ServerSocket servidor; // private static SSLSocket cliente; //Socket para conectarse con el cliente //private static String ip = "127.0.0.1"; //ip a la cual se conecta public String nick; private static Readable mostrarMensaje; public static PrincipalChat main;

public PrincipalChat(){ super("CLIENTE"); //Establece titulo al Frame campoTexto = new JTextField(); //crea el campo para texto campoTexto.setEditable(false); //No permite que sea editable el campo de texto add(campoTexto, BorderLayout.SOUTH); //Coloca el campo de texto en la parte superior

areaTexto = new JTextArea(); //Crear displayArea areaTexto.setEditable(false); add(new JScrollPane(areaTexto), BorderLayout.CENTER); areaTexto.setBackground(Color.lightGray); //Pone de color cyan al displayArea areaTexto.setForeground(Color.BLACK); //pinta azul la letra en el displayArea campoTexto.setForeground(Color.BLACK); //pinta toja la letra del mensaje a enviar //Crea menu Chat y submenu Salir, ademas agrega el submenu al menu JMenu menuArchivo = new JMenu("Servicio Chat"); JMenuItem salir = new JMenuItem("Salir"); menuArchivo.add(salir); //Agrega el submenu Salir al menu menuArchivo

JMenuBar barra = new JMenuBar(); //Crea la barra de menus setJMenuBar(barra); //Agrega barra de menus a la aplicacion barra.add(menuArchivo); //agrega menuArchivo a la barra de menus //Accion que se realiza cuando se presiona el submenu Salir salir.addActionListener(new ActionListener() { //clase interna anonima public void actionPerformed(ActionEvent e) { System.exit(0); //Sale de la aplicacion } }); setSize(600, 620); //Establecer tamano a ventana setVisible(true); //Pone visible la ventana }

//Para mostrar texto en displayArea public void mostrarMensaje(String mensaje) { areaTexto.append(mensaje + "\n"); } public void habilitarTexto(boolean editable) { campoTexto.setEditable(editable); } //Metodo que permite obtener nombre de la persona public void ingresarNick(){ nick = JOptionPane.showInputDialog(null, "Nombre de Usuario"); } /** * @param args the command line arguments */ public static void main(String[] args) { PrincipalChat main = new PrincipalChat(); //Instanciacion de la clase Principalchat main.setLocationRelativeTo(null); //Centrar el JFrame main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //habilita cerrar la ventana main.ingresarNick(); //LLamada al metodo ingresar nick

ExecutorService executor = Executors.newCachedThreadPool(); //Para correr los threads try { System.setProperty("javax.net.ssl.keyStore", Israel/workspace/Proyecto_Chat/AlmacenCl"); "C:/Users/Eduardo

System.setProperty("javax.net.ssl.keyStorePassword","edubrito"); System.setProperty("javax.net.ssl.trustStore","C:/Users/Eduardo Israel/workspace/Proyecto_Chat/AlmacenTrust");

SSLSocketFactory SSLSocketFactory.getDefault();

sslsocketfactory

(SSLSocketFactory)

String dirip = (JOptionPane.showInputDialog( null,"Direccion IP:", "Sumador", JOptionPane.QUESTION_MESSAGE) ); int ptoint = Integer.parseInt( JOptionPane.showInputDialog( null,"Puerto:", "Sumador", JOptionPane.QUESTION_MESSAGE) ); //System.out.print("Direccion IP: " ); //Scanner texto =new Scanner(System.in); //String dirip =texto.nextLine(); //System.out.print("Puerto:" ); //Scanner sc =new Scanner(System.in); //String pto= sc.nextLine(); //int ptoint= Integer.parseInt(pto); //Socket socket= new Socket(dirip,ptoint); main.mostrarMensaje("Conectando a Servidor ..."); //cliente = new Socket(InetAddress.getByName(dirip),ptoint); //comunicarme con el servidor, especificamos puerto cliente = sslsocketfactory.createSocket(InetAddress.getByName(dirip), ptoint); (SSLSocket)

SSLSession sesion = cliente.getSession(); X509Certificate certificate = (X509Certificate)sesion.getPeerCertificates()[0]; System.out.println("Propietario: "+certificate.getSubjectDN()); System.out.println("Emisor: "+certificate.getIssuerDN()); System.out.println("Numero "+certificate.getSerialNumber() ); System.out.println("to string: "+certificate.toString() );

Serie:

main.mostrarMensaje("Conectado a :" + cliente.getInetAddress().getHostName()); main.habilitarTexto(true); //habilita el texto //Ejecucion de los Threads executor.execute(new ThreadRecibe(cliente, main)); executor.execute(new ThreadEnvia(cliente, main)); } catch (IOException ex) { Logger.getLogger(PrincipalChat.class.getName()).log(Level.SEVERE, null, ex); } //Fin del catch finally { }

executor.shutdown(); }

} Funcin Enviar Mensajes

package cliente; import java.io.IOException; import java.io.ObjectOutputStream; import java.net.Socket; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.net.SocketException; import javax.net.ssl.SSLSocket; public class ThreadEnvia implements Runnable { private final PrincipalChat main; private ObjectOutputStream salida; private String mensaje; private SSLSocket conexion; public ThreadEnvia(SSLSocket conexion, final PrincipalChat main){ this.conexion = conexion; this.main = main; //Evento que ocurre al escribir en el campo de texto main.campoTexto.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { mensaje = event.getActionCommand(); enviarDatos(mensaje); //se envia el mensaje main.campoTexto.setText(""); //borra el texto del enterfield } //Fin metodo actionPerformed } );//Fin llamada a addActionListener } //enviar objeto a cliente private void enviarDatos(String mensaje){ try { salida.writeObject(main.nick+">>> " + mensaje); salida.flush(); //flush salida a cliente main.mostrarMensaje(main.nick+">>> " + mensaje); } //Fin try catch (IOException ioException){ main.mostrarMensaje("Error escribiendo Mensaje"); } //Fin catch

} //Fin metodo enviarDatos //manipula areaPantalla en el hilo despachador de eventos public void mostrarMensaje(String mensaje) { main.areaTexto.append(mensaje); } public void run() { try { salida = new ObjectOutputStream(conexion.getOutputStream()); salida.flush(); } catch (SocketException ex) { } catch (IOException ioException) { ioException.printStackTrace(); } catch (NullPointerException ex) { } } } Funcin Recibir Mensajes

package cliente; import java.io.EOFException; import java.io.IOException; import java.io.ObjectInputStream; import java.net.Socket; import java.net.SocketException; import java.util.logging.Level; import java.util.logging.Logger; import javax.net.ssl.SSLSocket; public class ThreadRecibe implements Runnable { private final PrincipalChat main; private String mensaje; private ObjectInputStream entrada; private SSLSocket cliente;

//Inicializar chatServer y configurar GUI public ThreadRecibe(SSLSocket cliente, PrincipalChat main){ this.cliente = cliente; this.main = main; } public void mostrarMensaje(String mensaje) { main.areaTexto.append(mensaje); }

public void run() { try { entrada = new ObjectInputStream(cliente.getInputStream()); } catch (IOException ex) { Logger.getLogger(ThreadRecibe.class.getName()).log(Level.SEVERE, null, ex); } do { //procesa los mensajes enviados desde el servidor try {//leer el mensaje y mostrarlo mensaje = (String) entrada.readObject(); //leer nuevo mensaje main.mostrarMensaje(mensaje); } //fin try catch (SocketException ex) { } catch (EOFException eofException) { main.mostrarMensaje("Fin de la conexion"); break; } //fin catch catch (IOException ex) { Logger.getLogger(ThreadRecibe.class.getName()).log(Level.SEVERE, null, ex); } catch (ClassNotFoundException classNotFoundException) { main.mostrarMensaje("Objeto desconocido"); } //fin catch } while (!mensaje.equals("Cliente>>> TERMINATE")); //Ejecuta hasta que el server escriba TERMINATE try { entrada.close(); //cierra entrada Stream cliente.close(); //cierra Socket } //Fin try catch (IOException ioException) { ioException.printStackTrace(); } //fin catch main.mostrarMensaje("Fin de la conexion"); System.exit(0); } } A continuacin se muestran los distintos archivos creados tanto para el cliente como para el servidor:

Figura 2: Programas y funciones para el cliente y para el servidor en Java-Eclipse.

También podría gustarte