JSSE
JSSE (Java Secure Socket Extension) es
un conjunto de paquetes que permiten el desarrollo de aplicaciones seguras en
Internet. Proporciona un marco y una implementación para la versión Java de los
protocolos SSL y TSL e incluye funcionalidad de
encriptación de datos, autenticación de servidores, integridad de mensajes y
autenticación de clientes.
Con JSSE,
los desarrolladores pueden ofrecer intercambio seguro de datos entre un cliente
y un servidor que ejecuta un protocolo de aplicación, tales como HTTP, Telnet o
FTP, a través de TCP/IP.
Las clases
de JSSE se encuentran en los paquetes javax.net
y javax.net.ssl.
SSL
Las clas SSLSocket y SSLServerSocket representan sockets seguros y son derivadas de las
ya familiares Socket y ServerSocket
respectivamente.
JSSE tiene dos clases SSLServerSocketFactory y SSLSocketFactory para la creación de
sockets seguros. No tienen constructor, se obtienen a través del método
estatico getDefault().
Para
obtener un socket servidor seguro o SSLServerSocket
SSLServerSocketFactory sfact = (SSLServerSocketFactory)
SSLServerSocketFactory.getDefault();
SSLServerSocket servidorSSL = (SSLServerSocket)
sfact.createServerSocket(puerto);
El método createServerSocket(int puerto) devuelve un socket de servidor
enlazado al puerto especificado. Para crear un SSLSocket:
SSLSocketFactory sfact = (SSLSocketFactory)
SSLSocketFactory.getDefault();
SSLSocket Cliente = (SSLSocket) sfact.createSocket(Host,
puerto);
Archivo SERVIDORSSL.JAVA
import java.io.*;
import javax.net.ssl.*;
public class ServidorSSL {
public static void main(String[] arg) throws IOException {
//System.setProperty("javax.net.ssl.keyStore",
System.getProperty("user.dir") + "\\AlmacenSSL");
//System.setProperty("javax.net.ssl.keyStorePassword",
"1234567");
int puerto = 6000;
SSLServerSocketFactory sfact =
(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
SSLServerSocket servidorSSL =
(SSLServerSocket) sfact.createServerSocket(puerto);
SSLSocket clienteConectado = null;
DataInputStream flujoEntrada = null; //FLUJO DE
ENTRADA DE CLIENTE
DataOutputStream flujoSalida = null; //FLUJO DE
SALIDA AL CLIENTE
for (int i = 1; i < 5; i++) {
System.out.println("Esperando
al cliente " + i);
clienteConectado = (SSLSocket) servidorSSL.accept();
flujoEntrada = new
DataInputStream(clienteConectado.getInputStream());
// EL CLIENTE ME ENVIA UN
MENSAJE
System.out.println("Recibiendo
del CLIENTE: " + i + " \n\t" + flujoEntrada.readUTF());
flujoSalida = new
DataOutputStream(clienteConectado.getOutputStream());
// ENVIO UN SALUDO AL CLIENTE
flujoSalida.writeUTF("SaIudos
al cliente del servidor");
}// Fin de for
// CERRAR STREAMS Y SOCKETS
flujoEntrada.close();
flujoSalida.close();
clienteConectado.close();
servidorSSL.close();
}// Fin de main
}// Fin de ServidorSSL
Crea una conexión sobre un socket servidor
seguro y que atenderá hasta cuatro conexiones de clientes que se identificarán
con un certificado válido. El servidor espera las conexiones, de cada cliente
que se conecta recibe un mensaje y a continuación le envía un saludo.
Archivo CLIENTESSL.JAVA
import java.io.*;
import
javax.net.ssl.*;
public class ClienteSSL {
public static void main(String[] args) throws Exception {
//System.setProperty("javax.net.ssl.trustStore",
System.getProperty("user.dir") + "\\UsuarioAlmacenSSL");
//System.setProperty("javax.net.ssl.trustStorePassword",
"890123");
String Host = "localhost";
int puerto = 6000;
System.out.println("PROGRAMA
CLIENTE INICIADO....");
SSLSocketFactory sfact =
(SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket Cliente = (SSLSocket) sfact.createSocket(Host, puerto);
// CREO FLUJO DE SALIDA AL SERVIDOR
DataOutputStream flujoSalida = new
DataOutputStream(Cliente.getOutputStream());
// ENVIO UN SALUDO AL SERVIDOR
flujoSalida.writeUTF("Saludos
al SERVIDOR DESDE EL CLIENTE");
// CREO FLUJO DE ENTRADA AL SERVIDOR
DataInputStream flujoEntrada = new
DataInputStream(Cliente.getInputStream());
// EL SERVIDOR ME ENVIA UN MENSAJE
System.out.println("Recibiendo
del SERVIDOR: \n\t" + flujoEntrada.readUTF());
/*------------------------------------------------------------------------------
//Información sobre la sesión SSL
SSLSession session = ((SSLSocket)
Cliente).getSession();
System.out.println("Host:
"+session.getPeerHost());
System.out.println("Cifrado:
" + session.getCipherSuite());
System.out.println("Protocolo:
" + session.getProtocol());
System.out.println("IDentificador:"
+ new BigInteger(session.getId()));
System.out.println("Creación de
la sesión: " + session.getCreationTime());
X509Certificate certificate =
(X509Certificate)session.getPeerCertificates()[0];
System.out.println("Propietario:
" + certificate.getSubjectDN());
System.out.println("Algoritmo:
" + certificate.getSigAlgName());
System.out.println("Tipo:
" + certificate.getType());
System.out.println("Emisor:
" + certificate.getIssuerDN());
System.out.println("Número
Serie: " + certificate.getSerialNumber());
------------------------------------------------------------------------------*/
// CERRAR STREAMS Y SOCKETS
flujoEntrada.close();
flujoSalida.close();
Cliente.close();
}// Fin de main
}// Fin de ClienteSSL
Envía un
mensaje al servidor y visualiza el que el servidor le devuelve.
El servidor
necesita disponer de un certificado que mostrar a los clientes que se conecten
a él. Usaremos la herramienta keytool
para crearlo, en el ejemplo le damos el nombre de AlmacenSSL y el valor de la clave es 1234567.
C:>keytool -genkey -alias claveSSL -keyalg RSA –keystore
AlmacenSSL -storepass 1234567
Para
ejecutar el programa servidor es necesario indicar el certificado que se
utilizará
C:>java
-Djavax.net.ssl.keyStore=AlmacenSSL -Djavax.net.ssl.keyStorePassword=1234567
ServidorSSL
Antes de
ejecutar el programa cliente necesitamos colocar el certificado en el keystore
del usuario, para ello lo exportamos a un fichero, le llamamos por ejemplo CertificadoSSL.cer
C:>keytool
-export -alias claveSSL -keystore AlmacenSSL -storepass 1234567 -file
Certificado.cer
Una vez que
tenemos el fichero exportado es necesario incorporarle al nuevo almacenamiento
para permitir realizar la validación. A continuación se crea un keystore de
nombre UsuarioAlmacenSSL con la clave
890123 y se incorpora el fichero de
certificado Certificado.cer. Esto lo
hacemos donde ejecutemos el cliente.
C:>keytool
-import -alias claveSSL -file Certificado.cer –keystore UsuarioAlmacenSSL
-storepass 890123
Para
ejecutar el programa cliente escribimos lo siguientes
C:>java
-Djavax.net.ssl.trustStore=UsuarioAlmacenSSL
-Djavax.net.ssl.trustStorePassword=890123 ClienteSSL
En estos
ejemplos para ejecutar el programa cliente y el servidor hemos establecido las propiedades JSSE desde la línea de
comandos usando la sintaxis –Dpropiedad=Valor.
También se pueden establecer desde el programa usando el método System.setProperty(String propiedad, String
valor).