带有SSL证书的Java HTTPS连接错误

带有SSL证书的Java HTTPS连接错误,java,ssl,Java,Ssl,我正在尝试在Apache服务器上使用StartSSL.com获得的SSL证书。与浏览器的连接很好,但当我尝试使用Java应用程序时,我得到了以下示例: 线程“main”javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX路径生成失败:sun.security.provider.certpath.SunCertPathBuilderException:找不到请求目标的有效证书路径 我不明

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

线程“main”javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX路径生成失败:sun.security.provider.certpath.SunCertPathBuilderException:找不到请求目标的有效证书路径


我不明白会出现什么问题,因为在浏览器中,我得到了带有绿色标签的SSL。

问题是您的Java不信任证书。您必须将其导入java的
信任库

# 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]
changeit是默认的信任库密码

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


导入方法是引用自

,据我所知,这与Java证书密钥库有关。java不接受您的证书。以下是如何将证书添加到Java trusted Certificates密钥库的链接:

像这样的问题已经有了,所以(像这个:)

通常的答案是,java客户机没有完成证书链所需的证书

如果您需要正确的证书验证,那么您必须找出证书链的故障点。如果您不这样做(因为这是一个概念验证或开发沙盒,或者其他什么),那么您可以通过将证书添加到您与客户机一起使用的信任存储中来轻松解决这个问题

编辑:
至于您的浏览器为什么接受此项,很可能是因为您的浏览器在链中有您需要的证书,或者您心不在焉地告诉浏览器信任证书,即使它也无法验证证书。

此消息是由于:

  • JRE的密钥库中没有根CA作为受信任项
  • 服务器未发送正确的链
  • 但是,2在您的情况下无效,因为浏览器能够构造链并验证证书

    因此,您需要获取根CA并将其作为受信任的条目放入JRE密钥库。有很多资源记录了“如何”。其中之一是:

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

    我建议使用基于apache http api构建的证书

    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());
    }
    
    import org.junit.Test;
    导入静态org.apache.http.HttpHeaders.ACCEPT;
    导入静态org.apache.http.HttpStatus.SC\u OK;
    导入静态org.apache.http.entity.ContentType.APPLICATION_XML;
    导入静态org.junit.Assert.assertEquals;
    公共类HttpRequestSSLTest{
    私有最终HttpRequest HttpRequest=HttpRequestBuilder.createGet(“https://mms.nw.ru/")
    .trustAllCertificates()
    .trustAllHosts()
    .addDefaultHeader(接受,应用程序_XML.getMimeType())
    .build();
    @试验
    public final void ignoresLandHostStest()引发异常{
    assertEquals(SC_OK,httpRequest.execute().getStatusCode());
    }
    

    }

    您可能没有将证书导入JVM。请参阅我自己的HTTPS库中的详细信息,我有一个方便的方法,可以接受所有服务器证书,包括自签名证书。对于某些客户端应用程序来说,这可能没问题(但对于主要浏览器来说肯定不行!)安全威胁在于,中间的一些人可能能够窃听甚至修改流量;但这是不可能的。它需要像国家安全局那样的资源;但我很确定NSA无论如何都可以侵入SSL:)@bayou.io事实上,这种情况可能发生在许多其他地方,例如公共WIFI。@Bruno-问题是浏览器用户会立即注意到证书篡改。因此,如果我们的客户是雷达下的一条小鱼,我们可能不会严格要求@bayou.io那是毫无意义的。这就是为什么有很多移动应用程序是不安全的,例如。谢谢!因此,如果我必须在web上共享java应用程序,我必须在该文件中插入密钥吗?顺便说一句,StartSSL告诉我:您必须将此网站设置为服务器的默认网站或使用专用IP地址。您认为呢?如果您想在web上共享java应用程序,您还必须向人们提供ssl文件,但可以通过浏览器轻松获取。。ssl证书可以通过多种方式轻松创建,即使您使用专用ip地址,如果您的证书不是由客户端的操作系统(Windows等)导入的,用户在进入您的网站时会在浏览器上看到警告。另一件事是,使用Comodo的另一个ssl证书,Java应用程序无需任何额外修改即可工作。所以问题就在于Java,不是吗?有没有办法修改Apache来解决这个问题?你可以通过谷歌搜索如何绕过java代码中的ssl,但不建议这样做谢谢!我还没有完全理解你的编辑。在Java中,我应该做些什么来解决这个问题?检查密钥库中已经受信任的ca根,并获取可以建立信任的服务器证书。或者,您可以附带自己的受信任存储,并为Java指定一个命令行选项以信任它。Djavax.net.ssl.trustStore=path/to/trustStore.jks