3

我有一个 Javafx 应用程序,它通过 HTTPS 将 GET 和 POST 请求发送到安全的 Web 服务。托管 web 服务的服务器上的 SSL 设置是单向 ssl,即 Javafx 应用程序验证服务器的身份,但服务器不验证胖客户端的身份。

应用程序服务器位于具有证书(由外部机构签署)的 F5 后面。

对于浏览器来说,这不是问题,因为浏览器本身会处理验证服务器的身份并向用户显示相关警告。但是对于胖客户端,我不确定在发送请求之前如何验证服务器的身份。请让我知道如何在 Javafx 应用程序中处理这个问题。

我之前在这里这里确实问过一个与此相关的问题,但这些都没有帮助。所以,请原谅我对这个话题的有限知识。

任何帮助,将不胜感激。

4

1 回答 1

5

如果您的证书在 Firefox/java 中不起作用,则很可能它的颁发者是 Firefox/java 未知的。

如何使其工作:

  1. 获取服务器的完整证书链。你可以用火狐做到这一点。查看证书 -> 详细信息-> 导出到 .pem 文件。在您的情况下,链将包含至少 2 个证书(cerver 证书和 CA 证书,CA 可能是自签名的,也可能不是)在 .pem 文件中导出 CA 证书。

  2. 现在您可以强制 java 信任该 CA,可以通过多种方式完成,例如,您可以在 jre cacerts 中添加 CA 证书或为 HttpsURLConnection 创建自定义 SSLContext。

  3. 如果您进行 DNS 或 etc.hosts 修改,请回滚。连接地址应与证书 CN 匹配,包括通配符。

  4. 使用该代码连接到您的服务器:

    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;
    }
    
于 2013-11-01T07:38:48.597 回答