当前位置: 首页 > 知识库问答 >
问题:

来自Java客户端的SSL错误,但在Firefox中有效

袁谭三
2023-03-14

我只是在我的服务器上设置SSL证书。我很确定他们是对的。当转到https://mydomain.com/myapp在浏览器中,页面正确加载,地址栏中显示绿色锁。

在Firefox上发帖子

如果我在Java客户机上发布同样的帖子,我会得到以下错误:

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

在我的服务器上,我已经把CA_ROOT证书放在JAVA.../jre/lib/Security/cacert密钥库中。

这是我在Java客户端发布的代码

URL url = new URL(Global.SERVER_URL);
HttpsURLConnection connection = null;
connection = (HttpsURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setReadTimeout(45000);
connection.setRequestProperty("Content-Type", "text/json");
connection.connect();

请注意:这不是一个自己签署的证书。它是由一个认证机构签发的

我感觉Glassfish没有发送完整的证书链。我看了看浏览器得到的证书,它是完整的证书链。我查看了SSL错误,这只是我的域的中间证书。

如何让Glassfish发送完整的证书链?

openssl。exe s_客户端-连接mydomain。com:443

退换商品

WARNING: can't open config file: /usr/local/ssl/openssl.cnf
Loading 'screen' into random state - done
CONNECTED(00000190)
depth=0 C = US, ST = <edited>, L = <edited>, O = <edited>, OU = <edited>, CN = <edited>
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 C = US, ST = <edited>, L = <edited>, O = <edited>, OU = <edited>, CN = <edited>
verify error:num=27:certificate not trusted
verify return:1
depth=0 C = US, ST = <edited>, L = <edited>, O = <edited>, OU = <edited>, CN = <edited>
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
 0 s:/C=US/ST=<edited>/L=<edited>/O=<edited>/OU=<edited>/CN=<edited>
   i:/O=Cybertrust Inc/CN=Cybertrust Public SureServer SV CA
---
Server certificate
-----BEGIN CERTIFICATE-----
<edited>
-----END CERTIFICATE-----
subject=/C=US/ST=<edited>/L=<edited>/O=<edited>/OU=<edited>/CN=<edited>
issuer=/O=Cybertrust Inc/CN=Cybertrust Public SureServer SV CA
---
No client certificate CA names sent
---
SSL handshake has read 1676 bytes and written 513 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-GCM-SHA256
    Session-ID: <edited>

    Session-ID-ctx:
    Master-Key: <edited>
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1410274974
    Timeout   : 300 (sec)
    Verify return code: 21 (unable to verify the first certificate)
---
read:errno=0

接受布鲁诺对这个概念的回答

其他详细信息:

  1. 获取密钥库资源管理器。这是一个浏览密钥库的绝佳GUI工具

共有3个答案

燕经国
2023-03-14

SSLHandshake异常:

当失败的连接看起来像这样时出现。通常表示存在某种类型的证书验证问题,很可能您的信任存储不包含它需要的受信任根证书。并表示客户端和服务器无法协商所需的安全级别。连接不再可用。

javax。网ssl。例外:太阳。安全验证器。ValidatorException:PKIX路径生成失败:sun。安全供应商。certpath。SunCertPathBuilderException:找不到请求目标的有效证书路径

详细示例使用下面的代码发送HTTP POST请求。

private void sendPost() throws Exception {

        String url = "https://selfsolve.apple.com/wcResults.do";
        URL obj = new URL(url);
        HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();

        //add reuqest header
        con.setRequestMethod("POST");
        con.setRequestProperty("User-Agent", "Mozilla/5.0");
        con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
        con.setRequestProperty("Content-Type", "text/json");

        String urlParameters = "sn=C02G8416DRJM&cn=&locale=&caller=&num=12345";

        // Send post request
        con.setDoOutput(true);
        DataOutputStream wr = new DataOutputStream(con.getOutputStream());
        wr.writeBytes(urlParameters);
        wr.flush();
        wr.close();

        int responseCode = con.getResponseCode();
        System.out.println("\nSending 'POST' request to URL : " + url);
        System.out.println("Post parameters : " + urlParameters);
        System.out.println("Response Code : " + responseCode);

        BufferedReader in = new BufferedReader(
                new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();

        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();

        //print result
        System.out.println(response.toString());

    }

如果响应代码为200,则表示看起来不错。
有关解决相同异常的更多详细信息,请参阅下面的链接。

  • 如何解决javax。网ssl。SSLHandshakeException错误
  • 测试受信任证书
  • 测试Java SSL连接
邵飞白
2023-03-14
---
Certificate chain
 0 s:/C=US/ST=<edited>/L=<edited>/O=<edited>/OU=<edited>/CN=<edited>
   i:/O=Cybertrust Inc/CN=Cybertrust Public SureServer SV CA
---

与您在评论中所说的不同,根据此输出,您的服务器没有发送任何中间证书。证书链只有一个证书(位于位置0):服务器证书。

在我的服务器上,我已经把CA_ROOT证书放在JAVA.../jre/lib/Security/cacert密钥库中。

在服务器端的信任库中添加中间证书不会对服务器提供的链产生影响(如果适用,它仅用于验证客户端)。

如本问题所述,您需要确保您的密钥库条目使用完整的链进行设置,遵循与本答案相同的过程

你在浏览器中看到的很可能是它重建的链,浏览器也可能知道这些中间CA证书,而JRE可能不知道(使用了不同的信任锚集):通过正确呈现完整的链,你只会增加默认JRE接受服务器证书的机会。(请注意,您不需要在链中显示根CA证书本身,这不会造成伤害,但这只是网络开销。)

谢承颜
2023-03-14

浏览器和Java使用不同的受信任根证书集,默认情况下浏览器从操作系统获取此信息,Java支持自己的列表,这就是为什么它在浏览器中可能是绿色的,而在Java中不支持

要检查哪些证书支持您的Java版本:

如果您没有看到您的证书,只需将其添加

 类似资料:
  • 问题内容: 是否可以使用Selenium和任何浏览器测试客户端SSL证书?例如,您可以创建一个Web驱动程序并为其提供虚拟证书吗?还是使用准备好的Firefox配置文件? 问题答案: 为SSL客户端证书创建Selenium Firefox测试配置文件 您需要准备Selenium的WebDriver Firefox配置文件,其中已导入了客户端证书。 首先,在测试代码中使用以下配置启动WebDrive

  • 当我在主机服务器的浏览器上运行这个应用程序时,我成功地获得了一个json对象(它不是我期望的json,但这是另一个问题)。但是,当我试图访问远程客户端上的站点时,我会得到一个403错误,指向我试图检索响应时的位置。有什么想法吗?

  • 问题内容: 我们的系统与多个Web服务提供商进行通信。它们都是从单个Java客户端应用程序调用的。到目前为止,所有的Web服务都已通过SSL进行,但是没有一个使用客户端证书。好吧,一个新的合作伙伴正在改变这一现状。 使应用程序使用证书进行调用很容易;设置和将做到这一点。但是,现在的问题是如何制作它,使其仅在调用该特定Web服务时使用证书。我想更一般地说,我们希望能够选择要使用的客户端证书(如果有)

  • 我已经用React和Apollo客户端在NestJS服务器上用GraphQL API制作了简单的CRUD应用程序。 我有一个简单的突变: “EmailScalar”类型主要检查“email”输入是否具有格式 它不能通过验证(因为电子邮件类型工作正常) 但当从客户端发送的查询通过验证时: NestJS服务器日志(来自下面的代码) 以前从未使用过NestJS、Apollo、React或GraphQL,

  • 如有任何帮助,我们将不胜感激。 PS:我使用的是java7

  • 问题内容: 我正在尝试确保通过Internet进行通信的Java客户端/服务器应用程序的连接安全。我的想法是将SSL套接字与自签名证书和客户端身份验证一起使用。我做了以下事情: 服务器:包含新的自签名证书的密钥库。 客户端:包含新的自签名证书的密钥库。 服务器:包含导出的客户端证书的信任库(来自上面的项目符号)。导出客户端证书并将其导入服务器的信任库 客户端:包含导出的服务器证书的信任库(从第一个