Connect to a secure outlet

I am trying to connect to a secure websocket using Jetty (or any other library).

The problem is that I am getting a "No Trusted Certificate" error message. I am using a self-signed certificate generated using keytool. What can be done?

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); } } 

Here is an attempt with the Tyrus websocket client, I am not getting an SSL error, but it is not printing anything:

 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(); } } } 

In comparison, this simple code in JS / node works

 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'); }); 

I would be happy to know about the websocket working client in Java

+6
source share
3 answers

There it is much simpler, there is no need to bother with trusted stores or configure X509TrustManagers or configure SSLContexts .

Just use what SslContextFactory comes with already ...

 package jetty.websocket; import java.net.URI; import java.util.concurrent.Future; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; import org.eclipse.jetty.websocket.api.annotations.WebSocket; import org.eclipse.jetty.websocket.client.WebSocketClient; @WebSocket public class SecureClientSocket { private static final Logger LOG = Log.getLogger(SecureClientSocket.class); public static void main(String[] args) { String url = "wss://qa.sockets.stackexchange.com/"; SslContextFactory sslContextFactory = new SslContextFactory(); sslContextFactory.setTrustAll(true); // The magic WebSocketClient client = new WebSocketClient(sslContextFactory); try { client.start(); SecureClientSocket socket = new SecureClientSocket(); Future<Session> fut = client.connect(socket,URI.create(url)); Session session = fut.get(); session.getRemote().sendString("Hello"); session.getRemote().sendString("155-questions-active"); } catch (Throwable t) { LOG.warn(t); } } @OnWebSocketConnect public void onConnect(Session sess) { LOG.info("onConnect({})",sess); } @OnWebSocketClose public void onClose(int statusCode, String reason) { LOG.info("onClose({}, {})", statusCode, reason); } @OnWebSocketError public void onError(Throwable cause) { LOG.warn(cause); } @OnWebSocketMessage public void onMessage(String msg) { LOG.info("onMessage() - {}", msg); } } 

Who will have such results ...

 2015-03-26 06:46:34.893:INFO::main: Logging initialized @62ms 2015-03-26 06:46:35.700:INFO:jw.SecureClientSocket: WebSocketClient@1849650547-15 : onConnect(WebSocketSession[websocket=JettyAnnotatedEventDriver[ jetty.websocket.SecureClientSocket@c299bbd ],behavior=CLIENT, connection=WebSocketClientConnection@7faf9b87 {IDLE}{f=Flusher[queueSize=0,aggregateSize=0,failure=null],g=Generator[CLIENT,validating], p=Parser@7a65105a [ExtensionStack,s=START,c=0,len=0,f=null, p=WebSocketPolicy@114c37d [behavior=CLIENT,maxTextMessageSize=65536,maxTextMessageBufferSize=32768,maxBinaryMessageSize=65536,maxBinaryMessageBufferSize=32768,asyncWriteTimeout=60000,idleTimeout=300000,inputBufferSize=4096]]}, remote=WebSocketRemoteEndpoint@7a2e4418 [batching=true],incoming=JettyAnnotatedEventDriver[ jetty.websocket.SecureClientSocket@c299bbd ],outgoing=ExtensionStack[queueSize=0,extensions=[],incoming=org.eclipse.jetty.websocket.common.WebSocketSession,outgoing=org.eclipse.jetty.websocket.client.io.WebSocketClientConnection]]) 2015-03-26 06:46:39.464:INFO:jw.SecureClientSocket: WebSocketClient@1849650547-14 : onMessage() - {"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"math.stackexchange.com\",\"id\":1207542,\"titleEncodedFancy\":\"Do we have this type of integral expression of Bessel function of the first kind?\",\"bodySummary\":\"Let $z=\\\\lambda+i\\\\mu$ with $\\\\mu&gt;0$. Then for any $r&gt;0$, $k=1,2,3, \\\\cdots$. Do we have the following identity\\n$$\\n\\\\int_{r}^{\\\\infty}{\\\\frac{t}{\\\\sqrt{t^2-r^2}}(\\\\frac{1}{t}\\\\frac{d}{dt})^k ...\",\"tags\":[\"analysis\",\"reference-request\",\"special-functions\"],\"lastActivityDate\":1427377599,\"url\":\"http://math.stackexchange.com/questions/1207542/do-we-have-this-type-of-integral-expression-of-bessel-function-of-the-first-kind\",\"ownerUrl\":\"http://math.stackexchange.com/users/37742/sun\",\"ownerDisplayName\":\"sun\",\"apiSiteParameter\":\"math\"}"} 2015-03-26 06:46:41.469:INFO:jw.SecureClientSocket: WebSocketClient@1849650547-16 : onMessage() - {"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"drupal.stackexchange.com\",\"id\":152924,\"titleEncodedFancy\":\"Features can export everything?\",\"bodySummary\":\"Built all blocks, menu, taxonomies, view etc in Drupal CMS on localhost machine, but I need to export everything to the live server. Is it possible to use features or just export sql?\\n\",\"tags\":[\"theming\"],\"lastActivityDate\":1427377601,\"url\":\"http://drupal.stackexchange.com/questions/152924/features-can-export-everything\",\"ownerUrl\":\"http://drupal.stackexchange.com/users/34551/joe\",\"ownerDisplayName\":\"joe\",\"apiSiteParameter\":\"drupal\"}"} 2015-03-26 06:46:44.034:INFO:jw.SecureClientSocket: WebSocketClient@1849650547-13 : onMessage() - {"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"wordpress.stackexchange.com\",\"id\":182350,\"titleEncodedFancy\":\"Create page from plugin, but have it completely hidden\",\"bodySummary\":\"I need to have a plugin create a page that is publicly accessible, but does NOT show up in the admin section anywhere, and cannot be deleted or modified.\\n\\nI thought maybe figuring out a way to have a ...\",\"tags\":[\"plugins\",\"pages\"],\"lastActivityDate\":1427377603,\"url\":\"http://wordpress.stackexchange.com/questions/182350/create-page-from-plugin-but-have-it-completely-hidden\",\"ownerUrl\":\"http://wordpress.stackexchange.com/users/45132/joel-worsham\",\"ownerDisplayName\":\"Joel Worsham\",\"apiSiteParameter\":\"wordpress\"}"} 
+12
source

Ok, I tried using your code to replicate the problem to no avail (get the certificate, import it using the keytool command and then run the code). my conclusion is as follows.

 2015-03-22 23:03:16.192:INFO::main: Logging initialized @503ms Socket Connected:WebSocketSession[websocket=JettyListenerEventDriver[com.ivan.Main],behavior=CLIENT, connection=WebSocketClientConnection@77ae29b0 {IDLE}{f=Flusher[queueSize=0,aggregateSize=0,failure=null],g=Generator[CLIENT,validating], p=Parser@4e086d6d [ExtensionStack,s=START,c=0,len=0,f=null, p=WebSocketPolicy@7c0ceccc [behavior=CLIENT,maxTextMessageSize=65536,maxTextMessageBufferSize=32768,maxBinaryMessageSize=65536,maxBinaryMessageBufferSize=32768,asyncWriteTimeout=60000,idleTimeout=300000,inputBufferSize=4096]]}, remote=WebSocketRemoteEndpoint@49f64 [batching=true],incoming=JettyListenerEventDriver[com.ivan.Main],outgoing=ExtensionStack[queueSize=0,extensions=[],incoming=org.eclipse.jetty.websocket.common.WebSocketSession,outgoing=org.eclipse.jetty.websocket.client.io.WebSocketClientConnection]] Received TEXT message: {"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"cogsci.stackexchange.com\",\"id\":9404,\"titleEncodedFancy\":\"What&#39;s the difference between repetition suppression and habituation?\",\"bodySummary\":\"Neural repetition suppression seems to be describing behavioral habituation on a neuronal level. What the difference between these two terms?\\n\",\"tags\":[\"cognitive-neuroscience\",\"terminology\",\"conditioning\",\"perceptual-learning\"],\"lastActivityDate\":1427036607,\"url\":\"http://cogsci.stackexchange.com/questions/9404/whats-the-difference-between-repetition-suppression-and-habituation\",\"ownerUrl\":\"http://cogsci.stackexchange.com/users/7569/recursive-farts\",\"ownerDisplayName\":\"RECURSIVE FARTS\",\"apiSiteParameter\":\"cogsci\"}"} Received TEXT message: {"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"mathematica.stackexchange.com\",\"id\":77933,\"titleEncodedFancy\":\"FunctionDomain doesn&#39;t work with If\",\"bodySummary\":\"When I call FunctionDomain for function defined by formule with If, for example \\n\\nf[x_]:=If[x&lt;0, x, x^3], \\n\\nI get \\\"Unable to find the domain with the available methods\\\". What should I do to get a ...\",\"tags\":[\"functions\"],\"lastActivityDate\":1427036609,\"url\":\"http://mathematica.stackexchange.com/questions/77933/functiondomain-doesnt-work-with-if\",\"ownerUrl\":\"http://mathematica.stackexchange.com/users/27150/adolzi\",\"ownerDisplayName\":\"adolzi\",\"apiSiteParameter\":\"mathematica\"}"} Received TEXT message: {"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"serverfault.com\",\"id\":677390,\"titleEncodedFancy\":\"Smart Array E200i battery on 350ML did not fix the warning message (battery failure)\",\"bodySummary\":\"I have got this warning message on the System Management in a Proliant server 350ML G5.\\n\\nDegraded Accelerator\\nName Value\\nStatus: Temporarily Disabled\\nError Code: Cache Disabled Low Batteries\\nSerial ...\",\"tags\":[\"hp-proliant\",\"hp-smart-array\"],\"lastActivityDate\":1427036609,\"url\":\"http://serverfault.com/questions/677390/smart-array-e200i-battery-on-350ml-did-not-fix-the-warning-message-battery-fail\",\"ownerUrl\":\"http://serverfault.com/users/164557/dlopezgonzalez\",\"ownerDisplayName\":\"dlopezgonzalez\",\"apiSiteParameter\":\"serverfault\"}"} Received TEXT message: {"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"askubuntu.com\",\"id\":599889,\"titleEncodedFancy\":\"Is downgrading back to 14.04 from 14.10 possible?\",\"bodySummary\":\"I am using Ubuntu 14.10 alongside Windows 7 and I want to degrade to 14.04. I made a bootable pendrive using Universal USB Installer and seems like the pendrive is working fine. On the Installer Boot ...\",\"tags\":[\"14.04\",\"boot\",\"upgrade\",\"downgrade\"],\"lastActivityDate\":1427036610,\"url\":\"http://askubuntu.com/questions/599889/is-downgrading-back-to-14-04-from-14-10-possible\",\"ownerUrl\":\"http://askubuntu.com/users/374332/pkj\",\"ownerDisplayName\":\"pkj\",\"apiSiteParameter\":\"askubuntu\"}"} Received TEXT message: {"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"superuser.com\",\"id\":814765,\"titleEncodedFancy\":\"External Harddrive Shutting Off and On Every So Often While Listening to Music\",\"bodySummary\":\"I am always listening to music on my PC (always via VLC Player) and every so often - maybe once every 2 songs, sometimes more frequently- the music stops playing (VLC buffer/progress bar stops ...\",\"tags\":[\"hard-drive\",\"power\",\"external\"],\"lastActivityDate\":1427036610,\"url\":\"http://superuser.com/questions/814765/external-harddrive-shutting-off-and-on-every-so-often-while-listening-to-music\",\"ownerUrl\":\"http://superuser.com/users/338547/supercookie47\",\"ownerDisplayName\":\"SuperCookie47\",\"apiSiteParameter\":\"superuser\"}"} Received TEXT message: {"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"math.stackexchange.com\",\"id\":1200778,\"titleEncodedFancy\":\"Continuity of a piecewise function at a specific point\",\"bodySummary\":\"I am having trouble proving the following function is not continuous at $x = 0$ using a formal definition of continuity.\\n\\n$\\nf(x) = \\\\left\\\\{\\n \\\\begin{array}{lr}\\n \\\\sin(\\\\frac{1}{x}) &amp; : x \\\\neq 0\\\\\\\\\\n ...\",\"tags\":[\"real-analysis\",\"functions\",\"continuity\",\"epsilon-delta\"],\"lastActivityDate\":1427036612,\"url\":\"http://math.stackexchange.com/questions/1200778/continuity-of-a-piecewise-function-at-a-specific-point\",\"ownerUrl\":\"http://math.stackexchange.com/users/222744/george\",\"ownerDisplayName\":\"George\",\"apiSiteParameter\":\"math\"}"} 

So if you want the web socket client running in java, I think you could just accept the whole certificate as the link that @tinker gave you.

The code should be like that. perhaps you could try and see what happens in your place.

 import java.net.URI; import java.security.cert.X509Certificate; import java.util.concurrent.Future; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; 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 Main extends WebSocketAdapter { public static void main(String[] args) { String url = "wss://qa.sockets.stackexchange.com/"; // or // "wss://echo.websocket.org" SslContextFactory sslContextFactory = new SslContextFactory(); TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } public void checkClientTrusted( java.security.cert.X509Certificate[] certs, String authType) { } public void checkServerTrusted( java.security.cert.X509Certificate[] certs, String authType) { } } }; try { SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); sslContextFactory.setSslContext(sc); WebSocketClient client = new WebSocketClient(sslContextFactory); client.start(); Future<Session> fut = client.connect(new Main(), URI.create(url)); Session session = fut.get(); session.getRemote().sendString("Hello"); session.getRemote().sendString("155-questions-active"); } 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); } } 
+2
source

Here, my Tyrus-java client uses a stub that I used to connect to my Jetty 9.3.6 server with HTTPS with a self-signed certificate (adapted from Tyrus websocket client , section 8.1):

  client = ClientManager.createClient(); //System.getProperties().put("javax.net.debug", "all"); // Useful for debugging SSL interaction // The keystore in the next two lines is the same keystore you used for running the server, // likely in ${jetty.base}/etc/keystore System.getProperties().put(SSLContextConfigurator.KEY_STORE_FILE, "/tmp/keystore"); System.getProperties().put(SSLContextConfigurator.TRUST_STORE_FILE, "/tmp/keystore"); // The following two passwords are what you used for your self-signed cert System.getProperties().put(SSLContextConfigurator.KEY_STORE_PASSWORD, "HumanReadablePassword"); System.getProperties().put(SSLContextConfigurator.TRUST_STORE_PASSWORD, "HumanReadablePassword"); 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); client.connectToServer(sillyWebSocketClient , ClientEndpointConfig.Builder.create().build(), new URI("wss://localhost:8443/sillyWebSocketServer/echo")); System.out.println ("Connected .... "); 

Where SillyWebSocketClient sillyWebSocketClient continues javax.websocket.Endpoint .

I am using Java 8 / Gradle 2.7, and my build.gradle looks like this:

 apply plugin: 'java' repositories { mavenCentral() } dependencies { compile 'javax:javaee-api:7.0' compile 'org.glassfish.grizzly:grizzly-core:2.3.23' compile 'org.glassfish.tyrus:tyrus-container-grizzly:1.2.1' compile 'org.glassfish.tyrus:tyrus-client:1.6' compile 'javax.websocket:javax.websocket-client-api:1.1' } 

Hope this helps.

+1
source

Source: https://habr.com/ru/post/984090/


All Articles