我有一个Javafx应用程序,通过HTTPS将GET和POST请求发送到安全的Web服务。托管web服务的服务器上的SSL设置是单向ssl,即Javafx应用程序验证服务器的标识,但服务器不验证胖客户端的标识。
应用程序服务器位于具有证书的F5后面(由外部机构签名)。
对于浏览器而言,这不会成为问题,因为浏览器本身会处理验证服务器的身份并向用户显示相关警告。但对于胖客户端,我不确定如何在发送请求之前验证服务器的身份。请让我知道如何在Javafx应用程序中处理这个问题。
我之前提出过与here和here相关的问题,但这些问题没有帮助。所以,请原谅我对这个主题的有限知识。
任何帮助都将不胜感激。
答案 0 :(得分:5)
如果你的证书在Firefox / java中不起作用,很可能它的发行者不为Firefox / java所知。
如何使其发挥作用:
获取服务器的完整证书链。你可以用Firefox做到这一点。查看证书 - >详情 - >导出到.pem文件。在您的案例链中,将包含至少2个证书(cerver证书和CA证书,CA可能是自签名的或可能不是).pem文件中的导出CA证书。
现在您可以强制java信任该CA,它可以通过各种方式完成,例如,您可以在jre cacerts中添加CA证书或为HttpsURLConnection创建自定义SSLContext。
如果您进行DNS或等主机修改,请回滚它。连接地址应与证书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;
}