我有一个Javafx应用程序,通过HTTPS将GET和POST请求发送到安全的Web服务.托管web服务的服务器上的SSL设置是单向ssl,即Javafx应用程序验证服务器的标识,但服务器不验证胖客户端的标识.
应用程序服务器位于具有证书的F5后面(由外部机构签名).
对于浏览器而言,这不会成为问题,因为浏览器本身会处理验证服务器的身份并向用户显示相关警告.但对于胖客户端,我不确定如何在发送请求之前验证服务器的身份.请告诉我如何在Javafx应用程序中处理此问题.
我确实问了一个与之前的here和here相关的问题,但那些没有帮助.所以,请原谅我对这个主题的有限知识.
任何帮助,将不胜感激.
解决方法:
如果您的证书在Firefox / java中不起作用,则很可能它的发行者不为Firefox / java所知.
如何使它工作:
>获取服务器的完整证书链.你可以用Firefox做到这一点.查看证书 – >详情 – >导出到.pem文件.在您的案例链中,将包含至少2个证书(cerver证书和CA证书,CA可能是自签名的或可能不是).在.pem文件中导出CA证书.
>现在您可以强制java信任该CA,它可以通过各种方式完成,例如,您可以在jre cacerts中添加CA证书或为HttpsURLConnection创建自定义SSLContext.
>如果您进行DNS或etchosts修改,请回滚它.连接地址应与证书CN匹配,包括通配符.
>使用该代码连接到您的服务器:
public void test() throws Exception {
URL u = new URL(
"https://my-server.com/my-webservices/data");
HttpsURLConnection http = (HttpsURLConnection) u.openConnection();
http.setSSLSocketFactory(createSSLContext().getSocketFactory());
http.setAllowUserInteraction(true);
http.setRequestMethod("GET");
http.connect();
InputStream is = http.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder stringBuilder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null)
{
stringBuilder.append(line
+ "\n");
}
System.out.println(stringBuilder.toString());
}
private SSLContext createSSLContext() throws Exception {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
FileInputStream in = new FileInputStream("path_to_ca_file.pem");
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(null);
try {
X509Certificate cacert = (X509Certificate) cf.generateCertificate(in);
trustStore.setCertificateEntry("ca", cacert);
} finally {
IOUtils.closeQuietly(in);
}
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(trustStore);
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, tmf.getTrustManagers(), new SecureRandom());
return sslContext;
}