我有问题,我想知道是否有人可以帮助我:)。
我在JAVA中开发了一个SSL通信客户端服务器,我正在尝试使用nginx对服务器进行负载均衡。 conf文件看起来:
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;
}
}
当我想使用使用nginx的客户端与我的服务器通信时,它告诉我:
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
这是我的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());
}
}
}
这是我的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());
}
}
}
如果你能帮助我,我将不胜感激!
答案 0 :(得分:1)
您是Java客户端不受信任的服务器证书。 Java使用信任库来确定它接受的证书。您需要从CA获取可信证书或将证书添加到信任库。
如果您不想购买证书,则需要更新Java。 This answer似乎涵盖了忽略错误或添加证书所需的内容。
你的nginx配置的相关部分是:
ssl_certificate C:/nginx-1.7.9/ssl/ServerKeyStore.crt;
ssl_certificate_key C:/nginx-1.7.9/ssl/ServerKeyStore.key;
您似乎已经了解了这一点,因为您已经定义了自定义信任库:
public static final String TRUSTTORE_LOCATION = "C:/CA/ClientKeyStore.jks";
所以它应该只是添加服务器证书的情况。