SOCKETS SEGUROS CON
SOCKETS SEGUROS CON
SOCKETS SEGUROS CON
SOCKETS SEGUROS CON
LIBRERÍAS DE OPENSSL
LIBRERÍAS DE OPENSSL
PROTOCOLO DE SEGURIDAD SSL PROTOCOLO DE SEGURIDAD SSL PROTOCOLO DE SEGURIDAD SSL PROTOCOLO DE SEGURIDAD SSL
FASE 1
FASE 2
FASE 3
FASE 4
Implementación del Protocolo Implementación del Protocolo
SSL en
SSL en OpenSSL OpenSSL
Se utilizan los objetos “SSL_CTX” y “SSL”
– SSL_CTX (Objeto de Contexto): Se utiliza para configurar los parámetros del protocolo
parámetros del protocolo
– SSL: El objeto SSL se asocia al objeto de contexto y hereda sus parámetros
– El objeto SSL se asocia también a un socket TCP – El objeto SSL se asocia también a un socket TCP
convencional
Para cargar los certificados de clave pública y
l i d tili l f i
claves privadas se utilizan las funciones:
– SSL_CTX_use_certificate() y SSL_CTX_use_PrivateKey()
Para verificar el certificado del servidor (u
Para verificar el certificado del servidor (u
opcionalmente el del cliente) se usan las clases:
– SSL_CTX_set_verify() y SSL_CTX_load_verify_locations();
Conexión SSL
Variables y Funciones OpenSSL Variables y Funciones OpenSSL
#include <openssl/ssl.h>
Variable de Contexto SSL_CTX * m_ctx
Se inicializa la variable de contexto Se inicializa la variable de contexto
SSL_CTX *SSL_CTX_new(SSL_METHOD *meth);
Esta función verifica el certificado recibido de la otra entidad
void SSL CTX set verify(SSL CTX *ctx,int mode, int (*callback)(int, X509 STORE CTX *));
void SSL_CTX_set_verify(SSL_CTX ctx,int mode, int ( callback)(int, X509_STORE_CTX ));
Esta función carga los certificados que la entidad utiliza para verificar el certificado recibido de la otra parte int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *Cafile, const char *CApath);
S bj t SSL i i i li l l d l i bl d t t
Se crea un objeto SSL que se inicializa con los valores de la variable de contexto SSL * SSL_new(SSL_CTX *ctx);
Se asocia un socket tradicional al objeto SSL. El protocolo SSL se implementará en el socket int SSL set fd(SSL *s int socket);
int SSL_set_fd(SSL s, int socket);
Se inicia el protocolo SSL del lado del cliente int SSL_connect(SSL *ssl);
Se envían datos por socket seguro
int SSL_write(SSL *ssl,const void *buf,int num);
Se reciben datos por el socket seguro
int SSL_read(SSL *ssl,void *buf,int num);
Conexión SSL
Variables y Funciones OpenSSL Variables y Funciones OpenSSL
#include <openssl/ssl.h>
Esta función se utiliza siempre en el servidor para cargar el certificado del protocolo SSL. Opcionalmente la
d tili l li t t ti f t l id
puede utilizar el cliente para autenticarse frente al servidor SSL_CTX_use_certificate(m_ctx, cert)
Esta función se utiliza siempre en el servidor para cargar la clave privada del certificado del protocolo SSL.
Opcionalmente la puede utilizar el cliente para cargar la clave privada del certificado que presenta al servidorp p p g p q p cuando hay autenticación del cliente.
SSL_CTX_use_PrivateKey(m_ctx, pkey)
Esta función la utiliza la entidad servidor para iniciar el protocolo SSL si todo ha ido bien (se han verificado los Esta función la utiliza la entidad servidor para iniciar el protocolo SSL si todo ha ido bien (se han verificado los certificados y se han recibido correctamente los mensajes del protocolo) se pueden intercambiar
datos de forma segura
if (SSL_accept(ssl) < 0) { .... }
Esta función permite la obtención del certificado de la otra entidad a partir de la conexión SSL X509 * SSL_get_peer_certificate(const SSL *s);
Certificados Necesarios para una Conexión Certificados Necesarios para una Conexión SSL sin Autenticación de Cliente SSL sin Autenticación de Cliente
openssl>
(Generación de un par clave pública‐privada)
l i d
genrsa ‐out ClavePrivada.pem 4096
Generación de un Certificado Autofirmado)
509 d 3650 k Cl P i d t C tifi d
req ‐new ‐x509 ‐days 3650 ‐key ClavePrivada.pem ‐out Certificado.pem (Creamos un certificado en formato p12, con la clave privada incorporada protegida con un clave cifrada con 3des (“ppppp)
protegida con un clave cifrada con 3des ( ppppp)
pkcs12 ‐export ‐in Certificado.pem ‐inkey ClavePrivada.pem ‐out cert.p12
Ficheros Obtenidos:
•cert.p12: Certificado de Clave pública+Clave privada
•Certificado.pem: Certificado de Clave PúblicaCertificado.pem: Certificado de Clave Pública
•ClavePrivada.pem: Clave privada
Conexión SSL sin Autenticación de Cliente
Certificado Servidor Autofirmado Certificado Servidor Autofirmado
Conexión SSL
Cliente Servidor
CAFILE “Certificado.pem” “cert.p12” CERTIFICADO SERVIDOR
Certificado Servidor
#define CAFILE "Certificado.pem
SSL_CTX *
m_ctx=SSL_CTX_new(SSLv23_server_method());
Clave Privada + Certificado Servidor
SSL_CTX * m_ctx = SSL_CTX_new(SSLv23_method());
SSL_CTX_set_verify(m_ctx,SSL_VERIFY_PEER|SSL_VERIFY_F AIL IF NO PEER CERT NULL);
if (!GetCertAndPrivateKey(&cert, &pkey)) SSL_CTX_use_certificate(m_ctx, cert) SSL_CTX_use_PrivateKey(m_ctx, pkey) AIL_IF_NO_PEER_CERT, NULL);
SSL_CTX_load_verify_locations(m_ctx, CAFILE, CADIR)
SSL * m_ssl=SSL_new(m_ctx);
s=connectTCP(host pto ser ice)
SSL *ssl = SSL_new(m_ctx);
sock = passiveTCP(service,5);
*pssock=accept(sock,(&fsin,(int FAR*)&alen);
s=connectTCP(host,pto_service);
SSL_set_fd(m_ssl,s);
if (SSL_connect(m_ssl) == -1) {}
SSL_write(m_ssl,,)/ SSL_read(m_ssl,,);
SSL_set_fd(ssl,*pssock);
if (SSL_accept(ssl) < 0) { .... } SSL_read(ssl,,)/SSL_write(ssl,,)
Conexión SSL con Autenticación de Cliente
C tifi d Cli t /S id A t fi d Cliente Conexión SSL
Certificado Cliente/Servidor Autofirmado Servidor
Cliente Servidor
“cert.p12”
“Certificado.pem”
“cert.p12”
“Certificado.pem”
CERT CLIENTE= CERT SERVIDOR
# d fi CAFILE "C tifi d CAFILE
Certificado Cliente
CERTIFICADO SERVIDOR
Clave Privada + Cert Servidor
Certificado Servidor
CERTIFICADO CLIENTE
Clave Privada + Cert Cliente CAFILE
#define CAFILE "Certificado.pem
SSL_CTX * m_ctx = SSL_CTX_new(SSLv23_method());
if (!GetCertAndPri ateKe (&cert &pke ))
# define CAFILE "Certificado.pem
SSL_CTX * m_ctx=SSL_CTX_new(SSLv23_server_method());
if (!GetCertAndPrivateKey(&cert, &pkey)) SSL_CTX_use_certificate(m_ctx, cert) if (!GetCertAndPrivateKey(&cert, &pkey))
SSL_CTX_use_certificate(m_ctx, cert) SSL_CTX_use_PrivateKey(m_ctx, pkey) SSL_CTX_set_verify(m_ctx, ……);
( )
SSL_CTX_use_PrivateKey(m_ctx, pkey)
SSL_CTX_set_verify(m_ctx,SSL_VERIFY_PEER|SSL_VERIFY_
FAIL_IF_NO_PEER_CERT, NULL);
SSL CTX load verify locations(m ctx CAFILE CADIR) SSL_CTX_load_verify_locations(m_ctx, CAFILE, CADIR)
SSL * m_ssl=SSL_new(m_ctx);
s=connectTCP(host,pto service);
SSL_CTX_load_verify_locations(m_ctx, CAFILE, CADIR)
SSL *ssl = SSL_new(m_ctx);
sock = passiveTCP(service,5);
* k t( k (&f i (i t FAR*)& l ) s connectTCP(host,pto_service);
SSL_set_fd(m_ssl,s);
if (SSL_connect(m_ssl) == -1) {}
SSL_write(m_ssl,,)/ SSL_read(m_ssl,,);
*pssock=accept(sock,(&fsin,(int FAR*)&alen);
SSL_set_fd(ssl,*pssock);
if (SSL_accept(ssl) < 0) { .... } SSL_read(ssl,,)/SSL_write(ssl,,)
SOCKETS SEGUROS EN JAVA
SOCKETS SEGUROS EN JAVA
SOCKETS SEGUROS EN JAVA
SOCKETS SEGUROS EN JAVA
Conexión SSL Conexión SSL
C tifi d S id
C tifi d S id A t fi A t fi d d (I) (I) Certificado Servidor
Certificado Servidor Autofirmado Autofirmado (I) (I)
Cliente Servidor
Conexión SSL
Truststore file Keystore File
Certificado Servidor (TrustCertEntry)
Clave Privada + Certificado Servidor (Key Entry)
“AlmacenTrust” “AlmacenSR”
( y) ( y y)
System.setProperty("javax.net.ssl.trustStore","AlmacenTrust");
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLS k tF t tD f lt()
System.setProperty("javax.net.ssl.keyStore","AlmacenSR");
System.setProperty("javax.net.ssl.keyStorePassword","oooooo");
SSLS S k tF t l k tf t
SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket)
sslsocketfactory.createSocket(dirip, ptoint);
SSLServerSocketFactory sslserversocketfactory =
(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
SSLServerSocket sslserversocket =(SSLServerSocket) sslserversocketfactory.createServerSocket(9999);
SLSocket sslsocket = (SSLSocket) sslserversocket.accept();
Conexión SSL Conexión SSL
C tifi d S id
C tifi d S id A t fi A t fi d d (II) (II) Certificado Servidor
Certificado Servidor Autofirmado Autofirmado (II) (II)
1. Generamos el par de claves pública y secreta y se almacenan en el almacen AlmacenSR
keytool -genkey -alias CertificadoAutofirmado -keyalg RSA -validity "100”
-keystore AlmacenSR -keypass oooooo -storepass oooooo keytool -list -v -keystore AlmacenSR
2 Generamos en un fichero .cer el certificado de clave publica
keytool -export -alias CertificadoAutofirmado -keystore AlmacenSR -rfc -file CertAutofirmado.cer
Conexión SSL Conexión SSL
C tifi d S id
C tifi d S id A t fi A t fi d d (III) (III) Certificado Servidor
Certificado Servidor Autofirmado Autofirmado (III) (III)
3. Metemos el Certificado Autofirmado en un almacén para que lo use el Cliente
keytool -import -alias CertificadoAutofirmado -file CertAutofirmado.cer keytool import alias CertificadoAutofirmado file CertAutofirmado.cer -keystore AlmacenTrust
keytool -list -v -keystore AlmacenTrusty y
Conexión SSL Conexión SSL
Certificado Servidor
Certificado Servidor Autofirmado Autofirmado (IV) (IV)
>keytool -genkey –alias CertificadoAutofirmado -keyalg RSA -validity "100" -keystore AlmacenSR -keypass oooooo -storepass oooooo
+Cuales son su nombre y su apellido?
[Unknown]: alumno1
+Cual es el nombre de su unidad de organizacion?
[Unknown]: fim
[ ]
+Cual es el nombre de su organizacion?
[Unknown]: upm
+Cual es el nombre de su ciudad o localidad?
[Unknown]: boa
[ ]
+Cual es el nombre de su estado o provincia?
[Unknown]: ma
+Cual es el c¾digo de paÝs de dos letras de la unidad?
[Unknown]: es
+Es correcto CN=alumno1, OU=fim, O=upm, L=boa, ST=ma, C=es?
[no]: y
Conexión SSL Conexión SSL
Certificado Servidor Autofirmado (V) Certificado Servidor Autofirmado (V)
>keytool -list -v -keystore AlmacenSR
Escriba la contrase±a del almacÚn de claves: oooooo Ú
Tipo de almacÚn de claves: jks
Proveedor de almacÚn de claves: SUN Su almacÚn de claves contiene entrada 1 Nombre de alias: certificadoautofirmado Fecha de creaci¾n: 22-sep-2009
Tipo de entrada: keyEntry
Longitud de la cadena de certificado: 1 Certificado[1]:
Propietario: CN=alumno1, OU=fim, O=upm, L=boa, ST=ma, C=es Emisor: CN=alumno1, OU=fim, O=upm, L=boa, ST=ma, C=es N·mero de serie: 4ab8a8c8
Vßlido desde: Tue Sep 22 12:36:56 CEST 2009 hasta: Thu Dec 31 11:36:56 CET 2009 Huellas digitales del certificado:
MD5: BC:F1:49:9A:02:5E:2E:91:27:C4:F9:FA:E3:3B:35:0A
SHA1: 45:A7:23:A0:BB:60:FE:7A:FA:C9:6F:B3:8E:CF:2E:D8:F6:3A:02:1E
*******************************************
Conexión SSL Conexión SSL
C tifi d S id
C tifi d S id A t fi A t fi d d (VI) (VI) Certificado Servidor
Certificado Servidor Autofirmado Autofirmado (VI) (VI)
>keytool -export –alias CertificadoAutofirmado -keystore AlmacenSR -rfc -file CertAutofirmado.cer Escriba la contrase±a del almacÚn de claves: oooooo
Escriba la contrase±a del almacÚn de claves: oooooo
Certificado almacenado en el archivo <CertAutofirmado.cer>
>keytool -import –alias CertificadoAutofirmado -file CertAutofirmado.cer -keystore AlmacenTrust Escriba la contrase±a del almacÚn de claves: oooooo
Escriba la contrase±a del almacÚn de claves: oooooo
Propietario: CN=alumno1, OU=fim, O=upm, L=boa, ST=ma, C=es Emisor: CN=alumno1, OU=fim, O=upm, L=boa, ST=ma, C=es N·mero de serie: 4ab8a8c8
Vßlido desde: Tue Sep 22 12:36:56 CEST 2009 hasta: Thu Dec 31 11:36:56 CET 2009 Vßlido desde: Tue Sep 22 12:36:56 CEST 2009 hasta: Thu Dec 31 11:36:56 CET 2009 Huellas digitales del certificado:
MD5: BC:F1:49:9A:02:5E:2E:91:27:C4:F9:FA:E3:3B:35:0A
SHA1: 45:A7:23:A0:BB:60:FE:7A:FA:C9:6F:B3:8E:CF:2E:D8:F6:3A:02:1E +Confiar en este certificado? [no]: yConfiar en este certificado? [no]: y
Se ha a±adido el certificado al almacÚn de claves
Conexión SSL Conexión SSL
Certificado Servidor
Certificado Servidor Autofirmado Autofirmado (VII) (VII)
>keytool -list -v -keystore AlmacenTrust
Escriba la contrase±a del almacÚn de claves: oooooo Tipo de almacÚn de claves: jks
Proveedor de almacÚn de claves: SUN Su almacÚn de claves contiene entrada 1 Su almacÚn de claves contiene entrada 1 Nombre de alias: certificadoautofirmado Fecha de creaci¾n: 22-sep-2009
Tipo de entrada: trustedCertEntry Tipo de entrada: trustedCertEntry
Propietario: CN=alumno1, OU=fim, O=upm, L=boa, ST=ma, C=es Emisor: CN=alumno1, OU=fim, O=upm, L=boa, ST=ma, C=es N·mero de serie: 4ab8a8c8
N·mero de serie: 4ab8a8c8
Vßlido desde: Tue Sep 22 12:36:56 CEST 2009 hasta: Thu Dec 31 11:36:56 CET 2009 Huellas digitales del certificado:
MD5: BC:F1:49:9A:02:5E:2E:91:27:C4:F9:FA:E3:3B:35:0A
SHA1: 45:A7:23:A0:BB:60:FE:7A:FA:C9:6F:B3:8E:CF:2E:D8:F6:3A:02:1E SHA1: 45:A7:23:A0:BB:60:FE:7A:FA:C9:6F:B3:8E:CF:2E:D8:F6:3A:02:1E
Conexión SSL Conexión SSL
Certificado Servidor
Certificado Servidor Autofirmado Autofirmado (VIII) (VIII)
import java.net.*;
Certificado Servidor
Certificado Servidor Autofirmado Autofirmado (VIII) (VIII) Código cliente Código cliente
import java.io.*;
import javax.net.ssl.*;
import java.util.*;
public class EchoClient {{
public static void
main(String[] arstring) {
try {
String dirip;
String dirip;
System.setProperty("javax.net.ssl.trustStore","AlmacenTrust");
InputStreamReader Flujo = new InputStreamReader(System.in);
BufferedReader teclado = new BufferedReader(Flujo);
S t t i t("Di i IP " ) System.out.print("Direccion IP: " );
dirip=teclado.readLine();
System.out.print("Puerto:" );
Scanner sc =new Scanner(System.in);( y );
String pto= sc.nextLine();
int ptoint= Integer.parseInt(pto);
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket) sslsocketfactory createSocket(dirip ptoint);
SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket(dirip, ptoint);
Conexión SSL Conexión SSL
Certificado Servidor
Certificado Servidor Autofirmado Autofirmado (IX) (IX) Certificado Servidor
Certificado Servidor Autofirmado Autofirmado (IX) (IX) Código cliente Código cliente
InputStream inputstream = System.in;
InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
OutputStream outputstream = sslsocket.getOutputStream();p p g p ();
OutputStreamWriter outputstreamwriter = new OutputStreamWriter(outputstream);
BufferedWriter bufferedwriter = new BufferedWriter(outputstreamwriter);
String string = null;
InputStream inputstream2 = sslsocket getInputStream();
InputStream inputstream2 = sslsocket.getInputStream();
InputStreamReader inputstreamreader2 = new InputStreamReader(inputstream2);
BufferedReader bufferedreader2 = new BufferedReader(inputstreamreader2);
while (!(string = bufferedreader.readLine()).equals("")) { b ff d it it ( t i '\ ')
bufferedwriter.write(string + '\n');
bufferedwriter.flush();
System.out.println(bufferedreader2.readLine() );
} }
catch (Exception exception) {
exception.printStackTrace();
}}
}//main }//public
Conexión SSL Conexión SSL
Certificado Servidor
Certificado Servidor Autofirmado Autofirmado (X) (X) Certificado Servidor
Certificado Servidor Autofirmado Autofirmado (X) (X) Código Servidor Código Servidor
import java.net.*; // Para ServerSocket
import java.util.*;
import javax.net.ssl.*; // Para SSLSockets
import java.io.*; //entrada/salida public class EchoServer {
public static void
main(String[] arstring) {
PrintStream p;
PrintStream p;
try {
System.setProperty("javax.net.ssl.keyStore","AlmacenSR");
System.setProperty("javax.net.ssl.keyStorePassword","oooooo");
SSLS S k tF t l k tf t (SSLS S k tF t )
SSLServerSocketFactory sslserversocketfactory =(SSLServerSocketFactory)
SSLServerSocketFactory.getDefault();
SSLServerSocket sslserversocket =(SSLServerSocket)
sslserversocketfactory.createServerSocket(9999);
SSLSocket sslsocket = (SSLSocket) sslserversocket.accept();( ) p ();
p=new PrintStream(sslsocket.getOutputStream());
InputStream inputstream = sslsocket.getInputStream();
InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
String string = null;
SSLSession sesion = sslsocket.getSession();
System.out.println("Host: "+sesion.getPeerHost());
Conexión SSL Conexión SSL
Certificado Servidor
Certificado Servidor Autofirmado Autofirmado (XI) (XI) Certificado Servidor
Certificado Servidor Autofirmado Autofirmado (XI) (XI) Código Servidor Código Servidor
while ((string = bufferedreader.readLine()) != null) { System.out.println(string);
System.out.flush();
Thread.currentThread().sleep(1000);
Thread.currentThread().sleep(1000);
p.println(string);
} }
catch (Exception exception) {
exception.printStackTrace();
} }//main
}//public
Conexión SSL con Autenticación Cliente (I) Conexión SSL con Autenticación Cliente (I)
Certificado Servidor/Cliente
Certificado Servidor/Cliente autofirmadoautofirmado Certificado Servidor/Cliente
Certificado Servidor/Cliente autofirmadoautofirmado
Conexión SSL
Cliente Servidor
“AlmacenTrust” “AlmacenSR”
“AlmacenTrust”
“AlmacenCL”
“AlmacenCL” = “AlmacenSR”
Truststore file Cliente
Certificado Autofirmado Keystore File Cliente
Clave Priv + Cert
Truststore file Servidor Keystore File Servidor
Clave Priv + Cert
AlmacenTrust AlmacenSR
Certificado Autofirmado AlmacenTrust
AlmacenCL
System.setProperty("javax.net.ssl.trustStore","AlmacenTrust"); System.setProperty("javax.net.ssl.keyStore","AlmacenSR");
S t tP t ("j t l k St P d" ” ")
Certificado Autofirmado (TrustCertEntry)
Clave Priv + Cert
Autofirmado (Key Entry)
Clave Priv Cert
Autofirmado (Key Entry) Certificado Autofirmado (TrustCertEntry)
System.setProperty("javax.net.ssl.keyStore","AlmacenCL");
System.setProperty("javax.net.ssl.keyStorePassword",” oooooo");
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
System.setProperty("javax.net.ssl.keyStorePassword",” ooooooo");
System.setProperty("javax.net.ssl.trustStore","AlmacenTrust");
SSLServerSocketFactory sslserversocketfactory =
(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket)
sslsocketfactory.createSocket(dirip, ptoint);
SSLServerSocket sslserversocket =(SSLServerSocket) sslserversocketfactory.createServerSocket(9999);
sslserversocket.setNeedClientAuth(true);
SLSocket sslsocket = (SSLSocket) sslserversocket accept();
SLSocket sslsocket = (SSLSocket) sslserversocket.accept();
Conexión SSL con Autenticación Cliente (II) Conexión SSL con Autenticación Cliente (II)
Certificado Servidor/Cliente
Certificado Servidor/Cliente autofirmadoautofirmado
import java.security.cert.X509Certificate; // para Manejo del Certificados
Certificado Servidor/Cliente
Certificado Servidor/Cliente autofirmadoautofirmado
// OBTENCION DE LA SESION Y DEL CERTIFICADO RECIBIDO DEL SERVIDOR Y EN EL CLIENTE SSLSession sesion = sslsocket.getSession();
System.out.println("Host: "+sesion.getPeerHost());
X509Certificate certificate = (X509Certificate)sesion.getPeerCertificates()[0]
System.out.println("Propietario: "+certificate.getSubjectDN());
System.out.println("Emisor: "+certificate.getIssuerDN());
System.out.println("Numero Serie: "+certificate.getSerialNumber() );
S t t i tl ("t t i " tifi t t St i () ) System.out.println("to string: "+certificate.toString() );
byte[] buf = certificate.getEncoded();
Fil O t tSt Fil O t tSt (" ") FileOutputStream os = new FileOutputStream("server.cer");
ó FileOutputStream os = new FileOutputStream(“cliente.cer");
os.write(buf);
l () os.close();