在 java 我怎样才能连接到 https 站点而不用担心安全证书

In java how can I connect to https sites without worrying about security certificates

当我尝试连接到 https 网站时,如下所示:

StringBuilder sb = new StringBuilder();
        URL oracle = new URL("https://company.com");
        URLConnection yc = oracle.openConnection();
        BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
        String inputLine;
        while ((inputLine = in.readLine()) != null)
            sb.append(inputLine);
        in.close();
        return sb.toString();

我明白了

sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387)
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
    at sun.security.validator.Validator.validate(Validator.java:260)
    at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1491)

如果我改用 http://company.com 它会起作用,但我想使用 https,因为这是他们说要使用的,我认为不安全的可能会被删除。

然而,当我看到类似的答案时,它谈到从我的浏览器 ectera 复制证书。我需要一个适用于任何人的解决方案 运行 任何计算机上的代码,而无需执行任何特殊操作。

我不关心 SSL 对这个项目的安全优势我只是希望能够连接到网站。

看来你已经被警告不要使用这种方法,所以我会坚持回答你的问题。我能够在我的机器上重现该问题,但我不知道为什么:我的浏览器可以顺利接受该站点的证书。

我尝试扩展您的代码以使其正常工作,但很快发现自己弄乱了 SSLContext、各种 crypto-providers 和服务提供商接口。我没有设法完成这种方法,实际上也不建议采用这种方法,因为它会更改 JVM 的全局安全设置,并且可能会产生不可预测的后果,具体取决于它正在做什么。

相反,我建议您查看 Apache HttpComponents library,它允许对连接的安全设置进行更多 fine-grained 控制。

以下将为创建的 HttpClient 实例禁用所有证书验证:

TrustStrategy veryNaive = new TrustStrategy() {
    @Override
    public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        return true;
    }
};

SSLContext sslcontext = SSLContexts.custom()
    .loadTrustMaterial(veryNaive)
    .build();

CloseableHttpClient httpclient = HttpClients.custom()
    .setSSLSocketFactory(new SSLConnectionSocketFactory(sslcontext))
    .build();

try {
    HttpGet httpget = new HttpGet("https://company.com");

    try (CloseableHttpResponse response = httpclient.execute(httpget);) {
        HttpEntity entity = response.getEntity();
        System.out.println(EntityUtils.toString(entity));
        EntityUtils.consume(entity);
    }
} finally {
    httpclient.close();
}

SSLContext 更改为 SSLContexts.createSystemDefault(); re-introduces 问题,只是为了证明它也存在于 Apache 库中。