Conexión a un websocket seguro
Estoy tratando de conectarme a un websocket seguro usando Jetty (o cualquier otra biblioteca).
El problema es que aparece el error "No se encontró un certificado confiable". Estoy usando un certificado autofirmado generado con keytool. ¿Qué se puede hacer?
import java.net.URI;
import java.util.concurrent.Future;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
import org.eclipse.jetty.websocket.client.WebSocketClient;
public class Socket extends WebSocketAdapter{
public static void main(String[] args) {
String url = "wss://qa.sockets.stackexchange.com/"; //or "wss://echo.websocket.org"
// making sure the the jvm find keystore
String JAVASEC="C:/Program Files/Java/jdk1.8.0_25/jre/lib/security/";
System.setProperty("javax.net.ssl.keyStore", JAVASEC+"keystore.jks");
System.setProperty("javax.net.ssl.trustStore", JAVASEC+"cacerts.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "changeit");
System.out.println(System.getProperty("javax.net.ssl.trustStore"));
SslContextFactory sslContextFactory = new SslContextFactory();
Resource keyStoreResource = Resource.newResource(Socket.class.getResource("/keystore.jks"));//generated with keytool
sslContextFactory.setKeyStoreResource(keyStoreResource);
sslContextFactory.setKeyStorePassword("password");
sslContextFactory.setKeyManagerPassword("password");
WebSocketClient client = new WebSocketClient(sslContextFactory);
try{
client.start();
Socket socket = new Socket();
Future<Session> fut = client.connect(socket,URI.create(url));
Session session = fut.get();
session.getRemote().sendString("Hello");
}
catch (Throwable t){
t.printStackTrace(System.err);
}
}
@Override
public void onWebSocketConnect(Session sess){
super.onWebSocketConnect(sess);
System.out.println("Socket Connected: " + sess);
}
@Override
public void onWebSocketText(String message){
super.onWebSocketText(message);
System.out.println("Received TEXT message: " + message);
}
@Override
public void onWebSocketClose(int statusCode, String reason){
super.onWebSocketClose(statusCode,reason);
System.out.println("Socket Closed: [" + statusCode + "] " + reason);
}
@Override
public void onWebSocketError(Throwable cause){
super.onWebSocketError(cause);
cause.printStackTrace(System.err);
}
}
Aquí hay un intento con el cliente websocket de Tyrus, no recibo un error SSL, pero no imprime nada:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import javax.websocket.ClientEndpointConfig;
import javax.websocket.CloseReason;
import javax.websocket.DeploymentException;
import javax.websocket.Endpoint;
import javax.websocket.EndpointConfig;
import javax.websocket.MessageHandler;
import javax.websocket.Session;
import org.glassfish.grizzly.ssl.SSLContextConfigurator;
import org.glassfish.grizzly.ssl.SSLEngineConfigurator;
import org.glassfish.tyrus.client.ClientManager;
import org.glassfish.tyrus.container.grizzly.GrizzlyEngine;
public class ClientWebSocketEndpoint extends Endpoint {
public static void main(String[] a) throws IOException{
ClientManager client = ClientManager.createClient();
//System.getProperties().put("javax.net.debug", "all");
final SSLContextConfigurator defaultConfig = new SSLContextConfigurator();
defaultConfig.retrieve(System.getProperties());
// or setup SSLContextConfigurator using its API.
SSLEngineConfigurator sslEngineConfigurator =
new SSLEngineConfigurator(defaultConfig, true, false, false);
client.getProperties().put(GrizzlyEngine.SSL_ENGINE_CONFIGURATOR,
sslEngineConfigurator);
Session session = null;
final ClientEndpointConfig cec = ClientEndpointConfig.Builder.create().build();
try {
session = client.connectToServer(ClientWebSocketEndpoint.class, cec, new URI("wss://qa.sockets.stackexchange.com/"));// or "wss://echo.websocket.org"
} catch (DeploymentException | URISyntaxException e) {
e.printStackTrace();
} finally {
if (session != null && session.isOpen())
session.close(new CloseReason(CloseReason.CloseCodes.GOING_AWAY, "Bye"));
}
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
br.readLine();
}
@Override
public void onOpen(Session session, EndpointConfig config) {
session.addMessageHandler(new MessageHandler.Whole<String>() {
@Ove,rride
public void onMessage(String message) {
System.out.println("Received message: "+message);
}
});
try {
session.getBasicRemote().sendText("1-questions-active");
session.getBasicRemote().sendText("155-questions-active");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
En comparación, este código simple en JS / nodo funciona
var WebSocket = require('ws')
, ws = new WebSocket('wss://qa.sockets.stackexchange.com/');//"wss://echo.websocket.org"
ws.on('message', function(message) {
console.log('received: %s', message);
});
ws.on('open', function() {
ws.send('155-questions-active');
ws.send('1-questions-active');
});
Me encantaría conocer un cliente websocket que funcione en Java