Reputation: 11
I have a problem and I wanted to know if someone can help me :)
I developed an SSL communication client server in JAVA and I am trying to load balance the server with nginx. the conf file look to that :
upstream backend {
least_conn;
server localhost:2010 max_fails=1 fail_timeout=20s;
server localhost:2011 max_fails=2 fail_timeout=20s;
}
server {
listen 443 ssl;
ssl_certificate C:/nginx-1.7.9/ssl/ServerKeyStore.crt;
ssl_certificate_key C:/nginx-1.7.9/ssl/ServerKeyStore.key;
#ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#proxy_connect_timeout 5s;
#proxy_timeout 3s;
location / {
proxy_pass http://backend;
}
}
And when I want to communicate with my Servers using my Client which uses nginx it tells me :
handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Here is my Client.JAVA :
package sslClient;
import java.io.*;
import javax.net.ssl.*;
public class EchoClient {
public static final boolean DEBUG = true;
public static final int HTTPS_PORT = 443;
public static final String HTTPS_HOST = "localhost";
public static final String TRUSTTORE_LOCATION = "C:/CA/ClientKeyStore.jks";
public static final String PAN = "12345678910111213";
public static String wrapHTML(String source) {
return "Content-Type: text-plain\n" + "Content-Length: "
+ source.length() + "\nServer: hcetoken" + "\n\n" + source;
}
public static void main(String[] args) {
System.setProperty("javax.net.ssl.trustStore", TRUSTTORE_LOCATION);
if (DEBUG)
System.setProperty("javax.net.debug", "ssl:record");
SSLSocketFactory f = (SSLSocketFactory) SSLSocketFactory.getDefault();
try {
SSLSocket c = (SSLSocket) f.createSocket(HTTPS_HOST, HTTPS_PORT);
c.startHandshake();
BufferedWriter w = new BufferedWriter(new OutputStreamWriter(
c.getOutputStream()));
BufferedReader r = new BufferedReader(new InputStreamReader(
c.getInputStream()));
PrintWriter sortie = new PrintWriter(w);
String msgHTML = wrapHTML(PAN);
System.out.println("Ecriture du client");
sortie.println(msgHTML);
sortie.flush();
// now read the socket
String m = null;
for(int i=0;i<10;++i)
{System.out.println("\n");}
System.out.println("Lecture du client");
while ((m = r.readLine()) != null) {
System.out.println("==================================================================");
System.out.println(m);
System.out.println("==================================================================");
}
System.out.println("Fin lecture du client");
for(int i=0;i<10;++i)
{System.out.println("\n");}
} catch (IOException e) {
System.err.println(e.toString());
}
}
}
and Here is my Server.JAVA :
public class EchoServer {
public static final boolean DEBUG = true;
public static final int HTTPS_PORT = 2010;
public static final String KEYSTORE_LOCATION = "C:/Keys/ServerKeyStore.jks";
public static final String KEYSTORE_PASSWORD = "myPassword";
// main program
public static void main(String argv[]) throws Exception {
// set system properties, alternatively you can also pass them as
// arguments like -Djavax.net.ssl.keyStore="keystore"....
System.setProperty("javax.net.ssl.keyStore", KEYSTORE_LOCATION);
System.setProperty("javax.net.ssl.keyStorePassword", KEYSTORE_PASSWORD);
if (DEBUG)
System.setProperty("javax.net.debug", "ssl:record");
EchoServer server = new EchoServer();
server.startServer();
}
// Start server
public void startServer() {
try {
ServerSocketFactory ssf = (SSLServerSocketFactory) SSLServerSocketFactory
.getDefault();
SSLServerSocket serversocket = (SSLServerSocket) ssf
.createServerSocket(HTTPS_PORT);
while (true) {
Socket client = serversocket.accept();
ProcessRequest cc = new ProcessRequest(client);
}
} catch (Exception e) {
System.out.println("Exception:" + e.getMessage());
}
}
}
class ProcessRequest extends Thread {
Socket client;
BufferedReader is;
DataOutputStream out;
InputStream iss;
PrintWriter sortie;
public static String wrapHTML(String source) {
return "Content-Type: text-plain\n" + "Content-Length: "
+ source.length() + "\nServer: hcetoken" + "\n\n" + source;
}
public ProcessRequest(Socket s) { // constructor
client = s;
try {
is = new BufferedReader(new InputStreamReader(
iss=client.getInputStream()));
out = new DataOutputStream(client.getOutputStream());
sortie = new PrintWriter(client.getOutputStream());
} catch (IOException e) {
System.out.println("Exception: " + e.getMessage());
}
this.start(); // Thread starts here...this start() will call run()
}
public void run() {
try {
// get a request and parse it.
String request = "";
for(int i=0;i<10;++i)
{System.out.println("\n");}
while(true)
{
request=is.readLine();
System.out.println(">"+request +" "+request.length());
if(request.length()==0)break;
}
request=is.readLine();
for(int i=0;i<10;++i)
{System.out.println("\n");}
System.out.println("=========================================================");
for(int i=0;i<10;++i)
{System.out.println("\n");}
System.out.println(request);
System.out.println("=========================================================");
for(int i=0;i<10;++i)
{System.out.println("\n");}
try {
sortie.println(wrapHTML(CryptographiePAN.cryptoPAN(request)));
sortie.flush();
} catch (Exception e) {
out.writeBytes("Content-Type: text/html\r\n");
out.writeBytes("HTTP/1.0 400 " + e.getMessage() + "\r\n");
out.flush();
} finally {
out.close();
}
client.close();
} catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
}
}
}
I would be grateful if you could help me!
Upvotes: 1
Views: 1043
Reputation: 4532
You a server certificate which is untrusted by the Java client. Java uses a truststore to determine the certificates it accepts. You either need to get a trusted certificate from a CA or add your certificate to the truststore.
If you don't want to buy a certificate then you need to update Java. This answer seems to cover what you need to either ignore the error or add the certificate.
The relevant part of your nginx config is:
ssl_certificate C:/nginx-1.7.9/ssl/ServerKeyStore.crt;
ssl_certificate_key C:/nginx-1.7.9/ssl/ServerKeyStore.key;
You seem to know about this as you have already defined a custom truststore:
public static final String TRUSTTORE_LOCATION = "C:/CA/ClientKeyStore.jks";
So it should just be a case of adding the server certificate to that.
Upvotes: 1