Para agregar SSL a tus códigos de servidor y cliente, necesitarás configurar correctamente el contexto SSL en ambas partes. Aquí tienes una guía general sobre cómo hacerlo:
Genera los certificados: Necesitarás generar un par de claves pública y privada para el servidor y el cliente. Puedes utilizar herramientas como OpenSSL o Java Keytool para generar los certificados.
Crear certificado con Keytool
1 |
keytool -genkey -alias servidor -keyalg RSA -keystore AlmacenSrv -storepass 1234567 |
Crear servidor seguro
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
import java.io.DataInputStream import java.io.DataOutputStream import java.io.FileInputStream import java.net.SocketException import java.security.KeyStore import javax.net.ssl.* class Servidor { fun iniciarServidor() { val puerto = 5556 val keyStorePath = "/Users/jesusn/IdeaProjects/untitled31/AlmacenSrv" val keyStorePassword = "1234567" val keyPassword = "1234567" try { val keyStore = KeyStore.getInstance("JKS") keyStore.load(FileInputStream(keyStorePath), keyStorePassword.toCharArray()) val keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()) keyManagerFactory.init(keyStore, keyPassword.toCharArray()) val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()) trustManagerFactory.init(keyStore) val sslContext = SSLContext.getInstance("TLSv1.3") // Asegurar compatibilidad TLS 1.2 sslContext.init(keyManagerFactory.keyManagers, trustManagerFactory.trustManagers, null) val sslServerSocketFactory = sslContext.serverSocketFactory val servidorSSL = sslServerSocketFactory.createServerSocket(puerto) as SSLServerSocket servidorSSL.needClientAuth = false // El cliente no necesita autenticarse con certificado println("Servidor SSL iniciado en el puerto $puerto. Esperando conexiones...") while (true) { try { val clienteConectado = servidorSSL.accept() as SSLSocket println("Cliente conectado: ${clienteConectado.inetAddress.hostAddress}") // Iniciar handshake antes de manejar al cliente clienteConectado.startHandshake() Thread { manejarCliente(clienteConectado) }.start() } catch (e: SocketException) { println("Error en la conexión: ${e.message}") } } } catch (e: Exception) { println("Error al iniciar el servidor: ${e.message}") e.printStackTrace() } } private fun manejarCliente(cliente: SSLSocket) { try { println("Inicio de comunicación con el cliente...") val flujoEntrada = DataInputStream(cliente.getInputStream()) val flujoSalida = DataOutputStream(cliente.getOutputStream()) // Leer mensaje del cliente val mensajeRecibido = flujoEntrada.readUTF() println("Mensaje recibido: $mensajeRecibido") // Enviar respuesta al cliente flujoSalida.writeUTF("Saludos del servidor SSL!") flujoSalida.flush() // IMPORTANTE: Asegurar que los datos se envían antes de cerrar // Esperar a que el cliente lea la respuesta antes de cerrar la conexión println("Esperando que el cliente lea la respuesta...") flujoSalida.close() // Cerrar el flujo de salida para indicar que no se enviarán más datos flujoEntrada.close() // Cerrar el flujo de entrada cliente.close() // Cerrar el socket println("Cliente desconectado correctamente.") } catch (e: Exception) { println("Error con cliente: ${e.message}") e.printStackTrace() } } } fun main() { val servidor = Servidor() servidor.iniciarServidor() } |
Crear cliente seguro
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
import java.io.DataInputStream import java.io.DataOutputStream import java.net.SocketTimeoutException import java.security.KeyStore import javax.net.ssl.* fun main() { val host = "192.168.0.38" // Cambia por la IP del servidor val puerto = 5556 val keyStorePath = "/Users/jesusn/IdeaProjects/untitled31/AlmacenSrv" val keyStorePassword = "1234567" try { val sslSocketFactory = createSSLSocketFactory(keyStorePath, keyStorePassword) val cliente = sslSocketFactory.createSocket(host, puerto) as SSLSocket cliente.soTimeout = 5000 // Configurar timeout para evitar bloqueos cliente.startHandshake() // Asegurar que el handshake SSL se complete antes de enviar datos val flujoSalida = DataOutputStream(cliente.getOutputStream()) val flujoEntrada = DataInputStream(cliente.getInputStream()) // Enviar mensaje al servidor println("Enviando mensaje al servidor...") flujoSalida.writeUTF("Saludos al SERVIDOR DESDE EL CLIENTE DESKTOP") flujoSalida.flush() // Esperar y leer respuesta del servidor println("Esperando respuesta del servidor...") val serverResponse = flujoEntrada.readUTF() println("Respuesta del servidor: $serverResponse") // Cerrar flujos y socket solo después de recibir la respuesta flujoEntrada.close() flujoSalida.close() cliente.close() } catch (e: SocketTimeoutException) { println("Error: El servidor no respondió dentro del tiempo de espera.") } catch (e: Exception) { println("Error en el cliente: ${e.message}") e.printStackTrace() } } fun createSSLSocketFactory(keyStorePath: String, keyStorePassword: String): SSLSocketFactory { val keyStore = KeyStore.getInstance("JKS") keyStore.load(java.io.FileInputStream(keyStorePath), keyStorePassword.toCharArray()) val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()) trustManagerFactory.init(keyStore) val sslContext = SSLContext.getInstance("TLSv1.3") // Asegurar compatibilidad con el servidor sslContext.init(null, trustManagerFactory.trustManagers, null) return sslContext.socketFactory } |