Https Client fails with SSL Peer Shut down incorrectly - java

The code below is supposed to ignore all certificates:
public class Application {
public static void main(String... args) {
System.out.println("Initiating... ");
// Create a trust manager that does not validate certificate chains
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) {
}
}
};
// Ignore differences between given hostname and certificate hostname
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) { return true; }
};
SSLContext sc = null;
// Install the all-trusting trust manager
try {
sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(hv);
} catch (GeneralSecurityException e) {
}
// Now you can access an https URL without having the certificate in the truststore
try {
URL url = new URL("https://localhost:30009/iPG/c2b/multione");
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
conn.setSSLSocketFactory(sc.getSocketFactory());
conn.setHostnameVerifier(hv);
InputStream is = conn.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String inputLine;
while ((inputLine = br.readLine()) != null) {
System.out.println(inputLine);
}
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
However I keep getting the error:
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1002)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1564)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:263)
at post.Application.main(Application.java:66)
Caused by: java.io.EOFException: SSL peer shut down incorrectly
at sun.security.ssl.InputRecord.read(InputRecord.java:505)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:983)
I don't understand why this is the case.

Related

How to disable SSL validation in spring-boot-starter-websocket

I am using dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<version>3.0.1</version>
</dependency>
and can't disable self-signed certificate verification
My code
StandardWebSocketClient client = new StandardWebSocketClient();
client.setUserProperties(Map.of(Constants.SSL_CONTEXT_PROPERTY, sslContext));
WebSocketStompClient stompClient = new WebSocketStompClient(client);
stompClient.setMessageConverter(new MappingJackson2MessageConverter());
stompClient.setInboundMessageSizeLimit(200000);
ClientWebsocketHandler sessionHandler = new ClientWebsocketHandler();
WebSocketHttpHeaders handshakeHeaders = new WebSocketHttpHeaders();
StompHeaders connectHeaders = new StompHeaders();
connectHeaders.add("username", "username");
connectHeaders.add("password", "password");
ListenableFuture<StompSession> connect = stompClient.connect("wss://111.111.11.111:8080/chat", handshakeHeaders, connectHeaders, sessionHandler);
i always get an error
Caused by: javax.net.ssl.SSLHandshakeException: No subject alternative names present
Browser connects successfully http://jxy.me/websocket-debug-tool/
i tried different ways
i added certificate with cacerts jdk
private static void disableSslVerification() {
try {
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}
};
// Install the all-trusting trust manager
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = (hostname, session) -> true;
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
} catch (NoSuchAlgorithmException | KeyManagementException e) {
e.printStackTrace();
}
}
StandardWebSocketClient client = new StandardWebSocketClient();
client.setUserProperties(Map.of(Constants.SSL_CONTEXT_PROPERTY, sslContext));
enter image description here

Can not fetch data (JSON) from url - Java

I'm making a java program and I want to fetch updates (json data) from URL of my website.
I used HttpURLConnection and Pass SSL Certificate.
I got this error while running:
javax.net.ssl.SSLException: Received fatal alert: internal_error
at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2011)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1113)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1363)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1391)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1375)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153)
(HTTPS URL)
I also try HTTP URL but the response code is 308
Pass SSL Certificate code:
public static void setupIgnoreSSLCertificate() throws NoSuchAlgorithmException, KeyManagementException {
final TrustManager[] trustManager = new TrustManager[]{new X509TrustManager() {
#Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) {
}
#Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) {
}
#Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}};
final SSLContext disease = SSLContext.getInstance("SSL");
disease.init(null, trustManager, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(disease.getSocketFactory());
final HostnameVerifier aids = (s, sslSession) -> true;
HttpsURLConnection.setDefaultHostnameVerifier(aids);
}
fetch code:
StringBuilder text = new StringBuilder();
try {
setupIgnoreSSLCertificate();
} catch (NoSuchAlgorithmException | KeyManagementException e) {
throw new RuntimeException(e);
}
try {
URL url = new URL(base + method);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.connect();
int code = connection.getResponseCode();
if(code != 200) {
System.out.println("Error code: " + code);
} else {
Scanner scanner = new Scanner(url.openStream());
while(scanner.hasNext()) {
text.append(scanner.nextLine());
}
scanner.close();
}
} catch(Exception e) {
e.printStackTrace();
}

java.net.SocketException: Connection reset - Exception while trying to consume https restful api in java8

Trying to access https service using below client which has certificates.
This work fine with Java7 when used in Java8 its throwing socket connection exception.
Should any other certificates need to be added ?
protected Client getClient() {
if (client == null) {
try {
TrustManager[] trustCertificates = new TrustManager[] { new X509TrustManager() {
#Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
#Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
#Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
} };
final SSLContext sslContext = SSLContext.getInstance(SSL);
sslContext.init(null, trustCertificates, new java.security.SecureRandom());
final HostnameVerifier verifiedHosts = new HostnameVerifier() {
#Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
ClientBuilder clientBuilder = ClientBuilder.newBuilder();
ClientConfig config = new ClientConfig();
config.register(JacksonJsonProvider.class);
config.register(Log4j2JerseyLoggingFilter.class);
return clientBuilder.sslContext(sslContext).hostnameVerifier(verifiedHosts).withConfig(config).build();
} catch (NoSuchAlgorithmException | KeyManagementException e) {
LOG.error("Client Builder Exception " + e);
}
}
return null;
}
Getting socket connection exception.
Caused by: java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:189)
at java.net.SocketInputStream.read(SocketInputStream.java:121)
at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
at sun.security.ssl.InputRecord.readV3Record(InputRecord.java:593)
at sun.security.ssl.InputRecord.read(InputRecord.java:529)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:954)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1343)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1371)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1355)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1281)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1256)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:250)
at org.glassfish.jersey.client.internal.HttpUrlConnector$4.getOutputStream(HttpUrlConnector.java:385)
at org.glassfish.jersey.message.internal.CommittingOutputStream.commitStream(CommittingOutputStream.java:200)
at org.glassfish.jersey.message.internal.CommittingOutputStream.commitStream(CommittingOutputStream.java:194)
Java 7 doesn't use TLSv1.2 by default but Java 8 does. The fact it worked in Java 7 points to the server not supporting TLSv1.2. Perhaps you need to change to whatever the server requires, along the lines of:
final SSLContext sslContext = SSLContext.getInstance("TLSv1");

How to bypass ssl certificate checking in java

I want access a SOAP webservice url having https hosted in a remote vm. I am getting an exception while accessing it using HttpURLConnection.
Here's my code:
import javax.net.ssl.*;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
/**
* Created by prasantabiswas on 07/03/17.
*/
public class Main
{
public static void main(String [] args)
{
try
{
URL url = new URL("https://myhost:8913/myservice/service?wsdl");
HttpURLConnection http = null;
if (url.getProtocol().toLowerCase().equals("https")) {
trustAllHosts();
HttpsURLConnection https = (HttpsURLConnection) url.openConnection();
https.setHostnameVerifier(DO_NOT_VERIFY);
http = https;
} else {
http = (HttpURLConnection) url.openConnection();
}
String SOAPAction="";
// http.setRequestProperty("Content-Length", String.valueOf(b.length));
http.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
http.setRequestProperty("SOAPAction", SOAPAction);
http.setRequestMethod("GET");
http.setDoOutput(true);
http.setDoInput(true);
OutputStream out = http.getOutputStream();
}
catch (Exception e)
{
e.printStackTrace();
}
}
final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
private static void trustAllHosts() {
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[] {};
}
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException
{
}
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
} };
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection
.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
e.printStackTrace();
}
}
}
I'm getting the following exception:
javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: Certificates does not conform to algorithm constraints
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1509)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1283)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1258)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:250)
at Main.main(Main.java:35)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: java.security.cert.CertificateException: Certificates does not conform to algorithm constraints
at sun.security.ssl.AbstractTrustManagerWrapper.checkAlgorithmConstraints(SSLContextImpl.java:1055)
at sun.security.ssl.AbstractTrustManagerWrapper.checkAdditionalTrust(SSLContextImpl.java:981)
at sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(SSLContextImpl.java:923)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1491)
... 18 more
Tried different solution from the google search, Non of them worked. I want to avoid using keytool because I will be running my tests on different vm.
Does anyone have any solution for this?
Using X509ExtendedTrustManager instead of X509TrustManager() solved the problem. Here's the example:
public void trustAllHosts()
{
try
{
TrustManager[] trustAllCerts = new TrustManager[]{
new X509ExtendedTrustManager()
{
#Override
public java.security.cert.X509Certificate[] getAcceptedIssuers()
{
return null;
}
#Override
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
{
}
#Override
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)
{
}
#Override
public void checkClientTrusted(java.security.cert.X509Certificate[] xcs, String string, Socket socket) throws CertificateException
{
}
#Override
public void checkServerTrusted(java.security.cert.X509Certificate[] xcs, String string, Socket socket) throws CertificateException
{
}
#Override
public void checkClientTrusted(java.security.cert.X509Certificate[] xcs, String string, SSLEngine ssle) throws CertificateException
{
}
#Override
public void checkServerTrusted(java.security.cert.X509Certificate[] xcs, String string, SSLEngine ssle) throws CertificateException
{
}
}
};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier()
{
#Override
public boolean verify(String hostname, SSLSession session)
{
return true;
}
};
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
}
catch (Exception e)
{
log.error("Error occurred",e);
}
}
Edit : Understand the vulnerability this would cause before using it. This is by no means recommended for production use.
The best way is to create a dummy trustmanager that trusts everything.
TrustManager[] dummyTrustManager = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
} };
Then use the dummy trustmanager to initialize the SSL Context
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, dummyTrustManager, new java.security.SecureRandom());
Finally use the SSLContext to open connection
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
URL url = new URL("https://myhost:8913/myservice/service?wsdl");
This question has already been answered here in more detail
Java: Overriding function to disable SSL certificate check
Update:
Above issue is due to certificate signature algorithm not being supported by Java. As per this post, later releases of Java 8 have disabled md5 algorithm.
To enable md5 support, locate java.security file under <jre_home>/lib/security
and locate the line (535)
jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024,
and remove MD5
Try with Apache HTTP client, this works for me.
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustStrategy() {
public boolean isTrusted(final X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
});
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build());
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
// GET or POST request with the client
...
Instead of using HttpsURLConnection.setDefaultSSLSocketFactory and your own implementation of TrustManager or X509ExtendedTrustManager, you can use TrustManagerFactory with a KeyStore with the certificate that issued the certificate you need to trust (for a self-signed certificate, this is the same as the host certificate) and call HttpsURLConnection.setSSLSocketFactory on the specific instance. This is both less code and avoids the security problems with trusting all HTTPS certicates.
In main:
if (url.getProtocol().toLowerCase().equals("https")) {
HttpsURLConnection https = (HttpsURLConnection) url.openConnection();
https.setSSLSocketFactory(createSSLSocketFactory());
http = https;
}
The method createSSLSocketFactory looks like this:
private static SSLSocketFactory createSSLSocketFactory() {
File crtFile = new File("server.crt");
Certificate certificate = CertificateFactory.getInstance("X.509").generateCertificate(new FileInputStream(crtFile));
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setCertificateEntry("server", certificate);
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
return sslContext.getSocketFactory();
}

SSL/TLS error ("no cipher suites in common") with Netty when trying to establish a secure connection between a frontend and a backend

I want to secure a TCP connection between a backend and a frontend. We use Netty to establish a TCP connection which works pretty well. Now, we want to secure this connection by using SSL/TLS. For that reason I created a certificate request:
openssl req -newkey rsa:2048 -keyout key.pem -out request.pem -subj '/C=DE/O=XX/ST=XX/L=XX/O=XX/OU=XX/CN=someaddress.de/emailAddress=support#xxx.de'
The certificate was then created by the CA.
The keystore was created with:
keytool -import -alias xxx -keystore xxx.keystore -file cert-xxx.pem
Server with Netty at the backend:
public StatefulTcpServer(MessageHandler messageHandler, int port, KeyStore keyStore, String keyStorePassword) {
this.messageHandler = messageHandler;
factory = new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool());
allChannels = new DefaultChannelGroup("clients");
initTLS(keyStore, keyStorePassword);
ServerBootstrap bootstrap = new ServerBootstrap(factory);
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
#Override
public ChannelPipeline getPipeline() {
ChannelPipeline pipeline = Channels.pipeline();
if (sslContext != null) {
SSLEngine sslEngine = sslContext.createSSLEngine();
sslEngine.setUseClientMode(false);
sslEngine.setEnabledCipherSuites(new String[] {
"TLS_RSA_WITH_AES_128_CBC_SHA"
});
pipeline.addLast("ssl", new SslHandler(sslEngine));
}
pipeline.addLast("compressor", new ZlibEncoder());
pipeline.addLast("decompressor", new ZlibDecoder());
pipeline.addLast("decoder", new JBossSerializationDecoder());
pipeline.addLast("encoder", new JBossSerializationEncoder());
pipeline.addLast("handler", StatefulTcpServer.this);
return pipeline;
}
});
bootstrap.setOption("child.tcpNoDelay", true);
bootstrap.setOption("child.keepAlive", true);
bootstrap.bind(new InetSocketAddress(port));
}
private void initTLS(KeyStore keyStore, String keyStorePassword) {
try {
if (keyStore != null) {
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, keyStorePassword.toCharArray());
sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), null, new SecureRandom());
}
}
catch (GeneralSecurityException e) {
logger.error("TLS connection could not be established", e);
sslContext = null;
}
}
Server with Netty in the frontend:
public void init(String backendHost, int backendPort, int timeOutSecs, boolean useTLS,
boolean acceptOnlyTrustworthyCertsForTLS) throws ConnectionFailedException {
channelFactory = new NioClientSocketChannelFactory(Executors.newCachedThreadPool(),
Executors.newCachedThreadPool());
if (useTLS) {
initTLS(acceptOnlyTrustworthyCertsForTLS);
}
ClientBootstrap bootstrap = new ClientBootstrap(channelFactory);
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
#Override
public ChannelPipeline getPipeline() {
ChannelPipeline pipeline = Channels.pipeline();
if (sslContext != null) {
SSLEngine sslEngine = sslContext.createSSLEngine();
sslEngine.setUseClientMode(true);
sslEngine.setEnabledCipherSuites(new String[] {
"TLS_RSA_WITH_AES_128_CBC_SHA"
});
pipeline.addLast("ssl", new SslHandler(sslEngine));
}
pipeline.addLast("compressor", new ZlibEncoder());
pipeline.addLast("decompressor", new ZlibDecoder());
pipeline.addLast("decoder", new JBossSerializationDecoder());
pipeline.addLast("encoder", new JBossSerializationEncoder());
pipeline.addLast("handler", StatefulTcpBackendCommunicator.this);
return pipeline;
}
});
bootstrap.setOption("tcpNoDelay", true);
bootstrap.setOption("keepAlive", true);
channelFuture = bootstrap.connect(new InetSocketAddress(backendHost, backendPort));
try {
boolean connected = channelFuture.await(timeOutSecs * 1000);
if (!connected || !channelFuture.isSuccess()) {
throw new ConnectionFailedException();
}
}
catch (InterruptedException e) {
logger.error(e.getMessage(), e);
}
}
private void initTLS(boolean acceptOnlyTrustworthyCertsForTLS) {
try {
TrustManager[] trustManagers;
if (acceptOnlyTrustworthyCertsForTLS) {
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory
.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
trustManagers = trustManagerFactory.getTrustManagers();
}
else {
trustManagers = new TrustManager[] {
new X509TrustManager() {
#Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
#Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {
return;
}
#Override
public void checkServerTrusted(X509Certificate[] certs, String authType) {
return;
}
}
};
}
sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagers, new SecureRandom());
}
catch (GeneralSecurityException e) {
logger.error("TLS connection could not be established. TLS is not used!", e);
sslContext = null;
}
}
When trying to establish the connection between frontend and backend I get an exception:
javax.net.ssl.SSLHandshakeException: no cipher suites in common
This post was unfortunately not helpful. Is there something wrong with the configuration of the servers? Or do I use the wrong certificate type?

Categories

Resources