Ich versuche, eine Verbindung zu einem gesicherten WebSocket mit Jetty (oder einer anderen Bibliothek) herzustellen.Verbinden mit einem gesicherten Websocket
Das Problem ist, ich bekomme einen Fehler "Kein vertrauenswürdiges Zertifikat gefunden". Ich verwende ein selbstsigniertes Zertifikat, das mit keytool erstellt wurde. Was könnte getan werden?
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);
}
}
Hier ist ein Versuch, mit Tyrus websocket Client, ich habe keine SSL-Fehler, aber es druckt nichts:
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>() {
@Override
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();
}
}
}
Im Vergleich mit diesem einfachen Code in JS/Knoten
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');
});
arbeitet
Ich würde mich freuen, einen funktionierenden Websocket-Client in Java zu kennen.
mögliches Duplikat von [Java wird angewiesen, selbstsigniertes SSL-Zertifikat zu akzeptieren] (http://stackoverflow.com/questions/2893819/telling-java-to-accept-self-signed-ssl-certificate) – tinker
@tinker I habe es gerade ausprobiert, bin mit einem browser zu https://qa.sockets.stackexchange.com/ gegangen, habe das zertifikat exportiert, und es in cacerts 'keytool -import ...' importiert und diesen Code nochmal ausgeführt, hab den gleicher Fehler "Kein vertrauenswürdiges Zertifikat gefunden" – caub
Haben Sie es mit einem Trust Store und dem richtigen Passwort ausgeführt? Stellen Sie sicher, dass Ihre JVM den richtigen Trust Store verwendet – tinker