Java HTTPS 连接与 SSL 证书错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30199806/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 16:39:19  来源:igfitidea点击:

Java HTTPS connection with SSL certificate Error

javassl

提问by I love coding

I'm trying to use the SSL certificate obtained with StartSSL.com on an Apache server. The connection with browser is fine, but when I try to use a Java application, I got this exeption:

我正在尝试在 Apache 服务器上使用通过 StartSSL.com 获得的 SSL 证书。与浏览器的连接很好,但是当我尝试使用 Java 应用程序时,我得到了这个例外:

Exception in thread "main" 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

线程“main”中的异常 javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效认证路径

I don't understand what could be the problem, because with the browser, I got the SSL with green label.

我不明白可能是什么问题,因为使用浏览器,我获得了带有绿色标签的 SSL。

回答by Sercan Ozdemir

The problem is your Java is not trusting the certificate. You have to import it to your java's truststore.

问题是您的 Java 不信任该证书。您必须将其导入到您的 java 的truststore.

# Copy the certificate into the directory Java_home\Jre\Lib\Security
# Change your directory to Java_home\Jre\Lib\Security>
# Import the certificate to a trust store.
# Here's the import command:

keytool -import -alias ca -file somecert.cer -keystore cacerts -storepass changeit [Return]

Trust this certificate: [Yes]

changeitis default truststore password.

changeit是默认的信任库密码。

For every certificate that you imported into your truststore you have to provide a new alias.

对于您导入信任库的每个证书,您必须提供一个新别名。

The import method is a quote from Here

导入方法引用自Here

回答by Khanna111

This message is due to:

此消息是由于:

  1. Either the JRE does not have the root CA as a trusted entry in its keystore.
  2. The server is not sending a proper chain.
  1. JRE 没有将根 CA 作为其密钥库中的可信条目。
  2. 服务器没有发送正确的链。

But, 2 is not valid in your case since the browser is able to construct the chain and validate the certificate.

但是, 2 在您的情况下无效,因为浏览器能够构建链并验证证书。

Consequently you need to get the root CA and put it in the JRE keystore as a trusted entry. There are lots of resources that document the "how". One of them is: https://access.redhat.com/documentation/en-US/Fuse_Message_Broker/5.3/html/Security_Guide/files/i379776.html

因此,您需要获取根 CA 并将其作为受信任条目放入 JRE 密钥库中。有很多资源记录了“如何”。其中之一是:https: //access.redhat.com/documentation/en-US/Fuse_Message_Broker/5.3/html/Security_Guide/files/i379776.html

EDIT 1: Since you want to share the java app, it would we worth the effort to get a certificate from a CA whose root is already trusted in the trust store for the Java versions that your app supports.

编辑 1:由于您想共享 Java 应用程序,因此我们值得努力从 CA 获取证书,该 CA 的根已经在您的应用程序支持的 Java 版本的信任存储中受到信任。

回答by Beno Arakelyan

I recomend use http-requestbuilt on apache http api.

我建议使用建立在 apache http api 上的http-request

import org.junit.Test;

import static org.apache.http.HttpHeaders.ACCEPT;
import static org.apache.http.HttpStatus.SC_OK;
import static org.apache.http.entity.ContentType.APPLICATION_XML;
import static org.junit.Assert.assertEquals;

public class HttpRequestSSLTest {

private final HttpRequest<?> httpRequest = HttpRequestBuilder.createGet("https://mms.nw.ru/")
        .trustAllCertificates()
        .trustAllHosts()
        .addDefaultHeader(ACCEPT, APPLICATION_XML.getMimeType())
        .build();

@Test
public final void ignoreSSLAndHostsTest() throws Exception {

    assertEquals(SC_OK, httpRequest.execute().getStatusCode());
}

}

}

回答by nullptrex

As far as I understand this is related to the Java Certificate Keystore. Your certificate is not accepted by java. Here is a link how to add your certificate to Java trusted Certificates keystore: https://docs.oracle.com/javase/tutorial/security/toolsign/rstep2.html

据我了解,这与 Java 证书密钥库有关。java 不接受您的证书。这是如何将您的证书添加到 Java 可信证书密钥库的链接:https: //docs.oracle.com/javase/tutorial/security/toolsign/rstep2.html

回答by Trevor Brown

There are a few questions like this already on SO (like this one: PKIX path building failed: unable to find valid certification path to requested target).

SO 上已经有一些这样的问题(例如:PKIX 路径构建失败:无法找到到请求目标的有效认证路径)。

The usual answer to this is that your java client doesn't have certificates needed to complete the certificate chain.

通常的答案是您的 Java 客户端没有完成证书链所需的证书。

If you need proper certificate validation, then you'll have to figure out where the certificate chain breaks down. If you don't (because this is a proof of concept or a dev sandbox, or whatever), then you can easily work around this by adding the certificate to the trust store you use with your client.

如果您需要适当的证书验证,那么您必须弄清楚证书链在哪里中断。如果您不这样做(因为这是一个概念证明或开发沙箱,或其他),那么您可以通过将证书添加到您与客户一起使用的信任存储中来轻松解决此问题。

Edit:

编辑:

As for why your browser accepts this, it's likely that either your browser has the certificates in the chain that you need or you've absentmindedly told your browser to trust the certificate even though it also wasn't able to validate the certificate.

至于您的浏览器为何接受这一点,很可能是您的浏览器在链中拥有您需要的证书,或者您心不在焉地告诉浏览器信任该证书,即使它也无法验证该证书。