programación de seguridad en java sesión 5 protocolo ssl

28
Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL1 Especialista en Aplicaciones y Servicios Web con Java Enterprise Programación de Seguridad en Java Sesión 5 Protocolo SSL

Upload: others

Post on 09-Jul-2022

15 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Programación de Seguridad en Java Sesión 5 Protocolo SSL

Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL1

Especialista en Aplicaciones y Servicios Web con Java Enterprise

Programación de Seguridad en Java

Sesión 5Protocolo SSL

Page 2: Programación de Seguridad en Java Sesión 5 Protocolo SSL

Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL2

SSL básico. Funcionamiento y HTTPSInstalando y configurando JSSECliente y servidor HTTPSProtegiendo “keystore” y passwordAutentificación del cliente

Índice

Page 3: Programación de Seguridad en Java Sesión 5 Protocolo SSL

Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL3

SSL básico. Funcionamiento y HTTPSInstalando y configurando JSSECliente y servidor HTTPSProtegiendo “keystore” y passwordAutentificación del cliente

SSL básico. Funcionamiento y HTTPS

Page 4: Programación de Seguridad en Java Sesión 5 Protocolo SSL

Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL4

Motivación: SSL: Protocolo de encriptación de comunicación cliente-servidor: POP, IMAP, telnet, FTP,…Pero sobre todo es el soporte para dotar de seguridad a HTTP: protocolo HTTPS.Implementación: extensión de los “sockets” que mantiene un canal de comunicación después de un “handshake”.Durante el “handshake” cliente y servidor construyen una “session-key”.

SSL básico. Funcionamiento y HTTPS

Page 5: Programación de Seguridad en Java Sesión 5 Protocolo SSL

Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL5

“Handshake” (esquema):

SSL básico. Funcionamiento y HTTPS

client_hello

server_hellocertificado_servidor(pedir_certificado)server_hello_done

(certificado_cliente)client_key_exchange(certificate_verify)change_cipher_spec

finished

change_cipher_specfinished

Page 6: Programación de Seguridad en Java Sesión 5 Protocolo SSL

Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL6

Handshake: 1. Cliente envía un client_hello que contiene:

Versión de SSL soportada por el cliente32 bytes de datos aleatoriosIdentificador de sesiónLista de “ciphers” soportadosLista de métodos de compresión soportados

2. Servidor responde un server_hello que contiene:Versión de SSL que selecciona de la lista del cliente32 bytes de datos aleatorios Identificador de sesiónCifradores seleccionados de la lista del cliente (RSA, RCA)Método de compresión (usualmente ninguno).

SSL básico. Funcionamiento y HTTPS

Page 7: Programación de Seguridad en Java Sesión 5 Protocolo SSL

Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL7

Handshake: 2. (sigue) Servidor envía un certificado X.509 firmado por

una CA y que contiene la clave pública del servidor. Opcionalmente puede pedir certificado al cliente. Después envía un server_hello_done y espera.

3. Cliente verifica el mensaje del servidor y si se le requiere un certificado se lo envía. Seguidamente envía un client_key_exchange con 48 bytes (sacados de los 32 del cliente y 32 del servidor) que se usan para construir la “session-key” que es encriptada por la clave pública del certificado del servidor.

SSL básico. Funcionamiento y HTTPS

Page 8: Programación de Seguridad en Java Sesión 5 Protocolo SSL

Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL8

Handshake: 3. (sigue) A continuación, el cliente envía un

cerificate_verify si se le pidió un certificado. En cualquier caso, después construye una clave simétrica con RC4 y una clave para el MAC que se usará para comprobar la integridad de los datos. Después envía un change_cipher_spec para indicar los parámetros del cifrado, y finalmente un finished.

4. Servidor responde con su change_cipher_specpara indicar los parámetros y con finished.

SSL básico. Funcionamiento y HTTPS

Page 9: Programación de Seguridad en Java Sesión 5 Protocolo SSL

Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL9

SSL básico. Funcionamiento y HTTPSInstalando y configurando JSSECliente y servidor HTTPSProtegiendo “keystore” y passwordAutentificación del cliente

Instalando y configurando JSSE

Page 10: Programación de Seguridad en Java Sesión 5 Protocolo SSL

Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL10

JSEE: Implementa SSL de forma transparente. Básicamente permite definir y manejar “sockets” seguros. Instalación y configuración:

Descargarlo de java.sun.com/products/jseeColocar jcert.jar, jnet.jar, jsse.jar en $JAVA_HOME/jre/lib/extModificar el fichero $JAVA_HOME/jre/lib/security/java.security para que contenga la línea que especifica un nuevo proveedor de seguridad

Instalando y configurando JSSE

Security.provider.x=com.sun.net.ssl.internal.ssl.Provider

Page 11: Programación de Seguridad en Java Sesión 5 Protocolo SSL

Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL11

SSL básico. Funcionamiento y HTTPSInstalando y configurando JSSECliente y servidor HTTPSProtegiendo “keystore” y passwordAutentificación del cliente

Cliente y servidor HTTPS

Page 12: Programación de Seguridad en Java Sesión 5 Protocolo SSL

Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL12

Cliente: (ClienteHTTPS.java) Hay que indicarle al manejador de URLs donde están las clases SSL:

java -Djava.protocol.handler.pkgs=com.sun.net.ssl.internal.www.protocolClienteHTTPS https://www.thawte.com

Alternativamente se puede hacer desde código a través de setProperty():

Cliente y servidor HTTPS

System.setProperty(

"java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");

Page 13: Programación de Seguridad en Java Sesión 5 Protocolo SSL

Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL13

Servidor: (ServidorHTTPS.java) Crear un “socket” SSL: Server Socket• Usar javax.net.ssl.SSLServerSocketFactory para

obtener una SSLServerSocketFactory.• Llamar a createServerSocket()

A partir de aquí el servidor actúa de forma transparente: accept(), InputStream (cliente), OutputStream(pantalla). Después construye una página HTML y finalmente cierra “streams” y el “socket”.

Cliente y servidor HTTPS

SSLServerSocketFactory ssf = (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();ServerSocket ss = ssf.createServerSocket(8080);

Page 14: Programación de Seguridad en Java Sesión 5 Protocolo SSL

Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL14

Servidor: (ServidorHTTPS.java) Sin embargo, si lanzamos java ServidorHTTPS se lanzaráuna excepción puesto que no se creado un certificado y una clave privada para el servidor SSLPara crearla con “keytool”: keytool –genkey –v –keyalg RSA –keystore .kestoreSiendo el CN=localhost. Así, para lanzar el servidor indicaremos a la MV el almacén que contiene el certificado y el password para acceder a él:

java -Djavax.net.ssl.keyStore=.keystore

-Djavax.net.ssl.keyStorePassword=scosco ServidorHTTPS

Cliente y servidor HTTPS

Page 15: Programación de Seguridad en Java Sesión 5 Protocolo SSL

Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL15

Servidor: (ServidorHTTPS.java) Tras esperar unos segundos desde el navegador atacaremos el puerto 8080: https://localhost:8080 donde está escuchando el servidor.Sin embargo, dado que el certificado es auto-firmado nuestro navegador no lo reconocerá y nos pedirá si queremos aceptarlo. Si decimos que sí se muestra una página HTML con “Hola!”. Para salvar las advertencias hay que usar un certificado de una CA reconocida por nuestra MV, como Verisign.

Cliente y servidor HTTPS

Page 16: Programación de Seguridad en Java Sesión 5 Protocolo SSL

Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL16

Cliente:(“trustore”) Para que el cliente confíe en el certificado auto-firmado del servidor podemos hacer que su trustStore (almacén de certificados en quien confía) sea el mismo almacén que el que contiene dicho certificado:

java –Djavax.net.ssl.trustStore=.keystore ClienteHTTPS https://localhost:8080/

El trustStore por defecto es el fichero$JRE_HOME/lib/security/cacerts

No obstante, podemos importar certificados en el cacerts de la siguiente forma:

keytool –impor –alias certificado –file certificado.cer –keystore cacerts

Cliente y servidor HTTPS

Page 17: Programación de Seguridad en Java Sesión 5 Protocolo SSL

Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL17

SSL básico. Funcionamiento y HTTPSInstalando y configurando JSSECliente y servidor HTTPSProtegiendo “keystore” y passwordAutentificación del cliente

Protegiendo “keystore” y password

Page 18: Programación de Seguridad en Java Sesión 5 Protocolo SSL

Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL18

Motivación: Pasar el almacén y su password por línea de comandosno es muy seguro (alguien puede verlo con un “ps”). Es más conveniente definir el password y cargar el almacén desde código. Utilizaremos las clases de com.sun.net.ssl: • TrustManagerFactory (en el cliente)• KeyManagerFactory (en el servidor)• SSLContext en ambos

Resultado: • ClienteSSLSocketsSun.java• ServidorSSLSocketsSun.java

Protegiendo “keystore” y password

Page 19: Programación de Seguridad en Java Sesión 5 Protocolo SSL

Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL19

Cliente: (ClienteSSLSocketsSun.java) Suponemos el password “conocido” para cargar el “keystore” que nos interesa:

Inicializamos una TrustManagerFactory

Protegiendo “keystore” y password

TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");

tmf.init(keystore);

char[] password = "scosco".toCharArray();KeyStore keystore = KeyStore.getInstance("JKS");keystore.load(new FileInputStream(".keystore"), password);

Page 20: Programación de Seguridad en Java Sesión 5 Protocolo SSL

Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL20

Cliente: (ClienteSSLSocketsSun.java) Ya podemos crear un SSLContext:

Este contexto permite definir una SSLSocketFactorypara que podamos implementar el cliente con “sockets”(sin basarnos en peticiones HTTPS)

Protegiendo “keystore” y password

SSLContext contexto = SSLContext.getInstance("TLS");TrustManager[] trustManagers = tmf.getTrustManagers();contexto.init(null, trustManagers, null);

Page 21: Programación de Seguridad en Java Sesión 5 Protocolo SSL

Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL21

Servidor: (ServidorSSLSocketsSun.java) Una vez conocido el password y cargado el “keystore”inicializará con éste una KeyManagerFactory y con ella un SSLContext:

Protegiendo “keystore” y password

KeyManagerFactorykmf = KeyManagerFactory.getInstance("SunX509");kmf.init(keystore, password);SSLContext contexto = SSLContext.getInstance("TLS");KeyManager[] keyManagers = kmf.getKeyManagers();contexto.init(keyManagers, null, null);SSLServerSocketFactory ssf = contexto.getServerSocketFactory();ServerSocket ss = ssf.createServerSocket(PORT);

Page 22: Programación de Seguridad en Java Sesión 5 Protocolo SSL

Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL22

SSL básico. Funcionamiento y HTTPSInstalando y configurando JSSECliente y servidor HTTPSProtegiendo “keystore” y passwordAutentificación del cliente

Autentificación del cliente

Page 23: Programación de Seguridad en Java Sesión 5 Protocolo SSL

Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL23

Motivación: Por defecto solo el servidor está obligado a autentificarse (el cliente se considera “anonimo”). Si queremos forzar la autentificación del cliente, éste deberá presentar un certificado. ServidorHTTPSAutorizando.java

Autentificación del cliente

// Utilizar una SocketFactory para crear sockets SSL:SSLServerSocketFactory ssf =(SSLServerSocketFactory)SSLServerSocketFactory.getDefault();SSLServerSocket ss =

(SSLServerSocket)ssf.createServerSocket(8080);// Requerir autentificación del clientess.setNeedClientAuth(true);

Page 24: Programación de Seguridad en Java Sesión 5 Protocolo SSL

Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL24

Cliente: (ClienteHTTPS.java) Pero antes, la autorización mútua fuerza a que el cliente incorpore en su trustStore un certificado del servidor (y viceversa:1. Keystore del cliente:keytool –genkey –v –keyalg RSA -keystore ks_cliente

(con “CN=sco” y clave “scosco”)

2. Keystore del servidor: keytool –genkey –v –keyalg RSA -keystore ks_servidor

(con “CN=localhost” y clave “dcciadccia”)

3. Certificado del servidorkeytool –export –v –file servidor.cer –keystore ks_servidor

Autentificación del cliente

Page 25: Programación de Seguridad en Java Sesión 5 Protocolo SSL

Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL25

Lanzamos servidorjava -Djavax.net.ssl.keyStore=ks_servidor

-Djavax.net.ssl.keyStorePassword=dcciadccia-Djavax.net.ssl.trustStore=ts_servidor

ServidorHTTPSAutorizando

Lanzamos clientejava -Djavax.net.ssl.keyStore=ks_cliente

-Djavax.net.ssl.keyStorePassword=scosco-Djavax.net.ssl.trustStore=ts_servidorClienteHTTPS https://localhost:8080

…y el cliente ya puede acceder a la página web.

Autentificación del cliente

Page 26: Programación de Seguridad en Java Sesión 5 Protocolo SSL

Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL26

ServidorHTTPSAutorizando2.javaAutentificar al cliente no en base al certificado completoen base a ciertos datos como el CN. Despues de accept()

Autentificación del cliente

boolean permitido = false;// Obtener la sesionSSLSession sesion = ((SSLSocket) s).getSession();// Comprobar la autentificación del cliente con el AutentificadorCNAutentificadorCN autentificador = newAutentificadorCN(sesion);try {autentificador.comprobarPermiso();permitido = true;

} catch (ExcepcionAutentificacion ea) {permitido = false;System.out.println("Acceso denegado." + ea);

}

Page 27: Programación de Seguridad en Java Sesión 5 Protocolo SSL

Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL27

AutentificadorCN.java

Autentificación del cliente

// 1. Obtener la secuencia de certificados.X509Certificate[] certChain = null;try {

certChain = mSession.getPeerCertificateChain();} catch (SSLPeerUnverifiedException spue) {throw new ExcepcionAutentificacion("Error cadena");}// 2. Obtener el certificado del clienteX509Certificate clientCert = certChain[0];// 3. Obtener el principal correspondiente al clientejava.security.Principal client = clientCert.getSubjectDN();// 4. Obtener el nombre del clienteString name = client.getName();// 5. Comprobar que CN=scoif (name.indexOf("CN=sco,")!=0) {throw new ExcepcionAutentificacion("Cliente no es sco");

}

Page 28: Programación de Seguridad en Java Sesión 5 Protocolo SSL

Programación de Seguridad en Java © 2003-2004 Depto. Ciencia Computación e IA SSL28

Ejercicio7.java…Usando JCEKS. Formato alternativo al JKS que utiliza PBE para encriptar las claves. • Desde keytool hay que usar la opción –storetype JCEKS• Dede línea de comandos –D.javax.net.ssl.keyStoreType=JCEKS

Se pide: modificar cliente y servidor basados en las clases de com.sun.net.ssl para que trabajen con almacenes de este tipo. ClienteSSLSocketsSun.java, ServidorSSLSocketsSun.java

Ejercicios…