Die Verbindung zu einem websocket gesichert
Ich versuche, eine Verbindung zu einem gesicherten websocket mit Steg (oder auch jede andere library).
Die Frage ist, bekomme ich ein "Keine vertrauenswürdigen Zertifikate gefunden" - Fehler. Ich bin ein selbst-signiertes Zertifikat mit keytool erzeugt. 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, bekomme ich keine SSL-Fehlermeldung, aber er 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/node funktioniert
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');
});
Ich würde glücklich sein zu wissen, dass ein arbeiten mit der websocket-client in Java
- möglich, Duplikat der erzählen java zu akzeptieren, sich selbst-signiertes ssl-Zertifikat
- Ich habe einfach versucht, es, ging zu den qa.sockets.stackexchange.com mit einem browser, exportieren Sie das Zertifikat und importiert es in cacerts
keytool -import ...
, und lief wieder in diesem code, habe den gleichen Fehler "Keine vertrauenswürdigen Zertifikate gefunden" - Hast du es auch mit einem trust store und das richtige Passwort? Sicherzustellen, dass Ihre JVM mit den richtigen trust store
- Gute Idee, das System.aus.println(System.setProperty("javax.net.ssl.trustStore")); null zurück, ich habe versucht, System.setProperty("javax.net.ssl.keyStore", "keystore.jks"); aber immer noch der gleiche Fehler
- versucht, mit dem absoluten Pfad zu
- Wenn Ihr Vertrauen store ist wieder null-das ist Ihr problem. Herauszufinden, warum Ihre Vertrauens-Shop ist nicht immer richtig eingestellt. Sind Sie eine Einstellung irgendwo?
- docs.oracle.com/cd/E19509-01/820-3503/6nf1il6er/index.html sehen, ob das hilft
- Sorry, es ist nicht null, sobald ich es natürlich, ich habe versucht, verschiedene Möglichkeiten, bearbeitet den code oben, scheint unmöglich...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gibt es einen viel einfacheren Weg, keine Notwendigkeit zu Chaos mit truststores, oder benutzerdefinierte
X509TrustManagers
oder besonders angefertigtSSLContexts
.Nur verwenden, was
SslContextFactory
kommt mit bereits ...Die Ergebnisse wie dieses ...
Gut, ich habe versucht mit deinem code das problem zu replizieren, ohne Erfolg ( das Zertifikat zu erhalten, importieren Sie Sie mit dem keytool-Befehl und dann den code ausführen ). meine Ausgabe ist wie diese.
Also ich denke, wenn Sie möchten, eine web-socket-client in java, ich denke, man könnte einfach annehmen, alle Zertifikate wie der link, den @tinker hat gab Sie.
Dem code sollte das so sein. vielleicht könnten Sie es versuchen und sehen, was passiert in Ihrem Ort.
new SslContextFactory(true);
(aka: Vertrauen alle Zertifikate)Hier ist meine Tyrus-java-client mithilfe der stub, die ich verwendet, um eine Verbindung zu meinem Jetty-9.3.6-server mit HTTPS mit einem selbstsignierten Zertifikat (adaptiert von Tyrus websocket-client, Abschnitt 8.1):
Wo
SillyWebSocketClient sillyWebSocketClient
erstrecktjavax.websocket.Endpoint
.Bin ich mit einer Java-8/Gradle 2.7 Umwelt und meine
build.gradle
sieht wie folgt aus:Hoffe, das hilft.