Java:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效证书路径

发布于 2024-11-27 05:44:19 字数 6999 浏览 1 评论 0原文

我有一个类将从 https 服务器下载文件。当我运行它时,它返回很多错误。看来我的证书有问题。是否可以忽略客户端-服务器身份验证?如果是这样,怎么办?

package com.da;

import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.CharBuffer;
import java.util.concurrent.Future;

import org.apache.http.HttpResponse;
import org.apache.http.client.utils.URIUtils;
import org.apache.http.impl.nio.client.DefaultHttpAsyncClient;
import org.apache.http.nio.IOControl;
import org.apache.http.nio.client.HttpAsyncClient;
import org.apache.http.nio.client.methods.AsyncCharConsumer;
import org.apache.http.nio.client.methods.HttpAsyncGet;
import org.apache.http.nio.client.methods.HttpAsyncPost;

public class RSDDownloadFile {
    static FileOutputStream fos;

    public void DownloadFile(String URI, String Request) throws Exception
    {
        java.net.URI uri = URIUtils.createURI("https", "176.66.3.69:6443", -1, "download.aspx",
                "Lang=EN&AuthToken=package", null);
        System.out.println("URI Query: " + uri.toString());

        HttpAsyncClient httpclient = new DefaultHttpAsyncClient();
        httpclient.start();
        try {
            Future<Boolean> future = httpclient.execute(
                    new HttpAsyncGet(uri),
                    new ResponseCallback(), null);

            Boolean result = future.get();
            if (result != null && result.booleanValue()) {
                System.out.println("\nRequest successfully executed");
            } else {
                System.out.println("Request failed");
            }              
        } 
        catch(Exception e){
            System.out.println("[DownloadFile] Exception: " + e.getMessage());
        }
        finally {
            System.out.println("Shutting down");
            httpclient.shutdown();
        }
        System.out.println("Done");  

    }

    static class ResponseCallback extends AsyncCharConsumer<Boolean> {

        @Override
        protected void onResponseReceived(final HttpResponse response) {
             System.out.println("Response: " + response.getStatusLine());
             System.out.println("Header: " + response.toString());
             try {   
                 //if(response.getStatusLine().getStatusCode()==200)
                     fos = new FileOutputStream( "Response.html" );
             }catch(Exception e){
                 System.out.println("[onResponseReceived] Exception: " + e.getMessage());
             }
        }

        @Override
        protected void onCharReceived(final CharBuffer buf, final IOControl ioctrl) throws IOException {
            try
            {
                while (buf.hasRemaining()) 
                {
                    //System.out.print(buf.get());
                    fos.write(buf.get());
                }
            }catch(Exception e)
            {
                System.out.println("[onCharReceived] Exception: " + e.getMessage());
            }
        }

        @Override
        protected void onCleanup() {
            try
            {             
                if(fos!=null)
                    fos.close();
            }catch(Exception e){
                System.out.println("[onCleanup] Exception: " + e.getMessage());         
            }
             System.out.println("onCleanup()");
        }

        @Override
        protected Boolean buildResult() {
            return Boolean.TRUE;
        }

    }
}

错误:

URI Query: https://176.66.3.69:6443/download.aspx?Lang=EN&AuthToken=package
Aug 2, 2011 3:47:57 PM org.apache.http.impl.nio.client.NHttpClientProtocolHandler exception
SEVERE: I/O error: General SSLEngine problem
javax.net.ssl.SSLHandshakeException: General SSLEngine problem
    at com.sun.net.ssl.internal.ssl.Handshaker.checkThrown(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.checkTaskThrown(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.writeAppRecord(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.wrap(Unknown Source)
    at javax.net.ssl.SSLEngine.wrap(Unknown Source)
    at org.apache.http.impl.nio.reactor.SSLIOSession.doHandshake(SSLIOSession.java:154)
    at org.apache.http.impl.nio.reactor.SSLIOSession.isAppInputReady(SSLIOSession.java:276)
    at org.apache.http.impl.nio.client.InternalClientEventDispatch.inputReady(InternalClientEventDispatch.java:79)
    at org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:161)
    at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:335)
    at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:315)
    at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:275)
    at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104)
    at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:542)
    at java.lang.Thread.run(Unknown Source)
Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(Unknown Source)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
    at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
    at com.sun.net.ssl.internal.ssl.Handshaker$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.net.ssl.internal.ssl.Handshaker$DelegatedTask.run(Unknown Source)
    at org.apache.http.impl.nio.reactor.SSLIOSession.doHandshake(SSLIOSession.java:180)
    ... 9 more
Caused by: 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(Unknown Source)
    at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
    at sun.security.validator.Validator.validate(Unknown Source)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
    at com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(Unknown Source)
    ... 16 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
    at java.security.cert.CertPathBuilder.build(Unknown Source)
    ... 21 more
onCleanup()

[DownloadFile] Exception: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
Shutting down
Done

I have a class that will download a file from a https server. When I run it, it returns a lot of errors. It seems that I have a problem with my certificate. Is it possible to ignore the client-server authentication? If so, how?

package com.da;

import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.CharBuffer;
import java.util.concurrent.Future;

import org.apache.http.HttpResponse;
import org.apache.http.client.utils.URIUtils;
import org.apache.http.impl.nio.client.DefaultHttpAsyncClient;
import org.apache.http.nio.IOControl;
import org.apache.http.nio.client.HttpAsyncClient;
import org.apache.http.nio.client.methods.AsyncCharConsumer;
import org.apache.http.nio.client.methods.HttpAsyncGet;
import org.apache.http.nio.client.methods.HttpAsyncPost;

public class RSDDownloadFile {
    static FileOutputStream fos;

    public void DownloadFile(String URI, String Request) throws Exception
    {
        java.net.URI uri = URIUtils.createURI("https", "176.66.3.69:6443", -1, "download.aspx",
                "Lang=EN&AuthToken=package", null);
        System.out.println("URI Query: " + uri.toString());

        HttpAsyncClient httpclient = new DefaultHttpAsyncClient();
        httpclient.start();
        try {
            Future<Boolean> future = httpclient.execute(
                    new HttpAsyncGet(uri),
                    new ResponseCallback(), null);

            Boolean result = future.get();
            if (result != null && result.booleanValue()) {
                System.out.println("\nRequest successfully executed");
            } else {
                System.out.println("Request failed");
            }              
        } 
        catch(Exception e){
            System.out.println("[DownloadFile] Exception: " + e.getMessage());
        }
        finally {
            System.out.println("Shutting down");
            httpclient.shutdown();
        }
        System.out.println("Done");  

    }

    static class ResponseCallback extends AsyncCharConsumer<Boolean> {

        @Override
        protected void onResponseReceived(final HttpResponse response) {
             System.out.println("Response: " + response.getStatusLine());
             System.out.println("Header: " + response.toString());
             try {   
                 //if(response.getStatusLine().getStatusCode()==200)
                     fos = new FileOutputStream( "Response.html" );
             }catch(Exception e){
                 System.out.println("[onResponseReceived] Exception: " + e.getMessage());
             }
        }

        @Override
        protected void onCharReceived(final CharBuffer buf, final IOControl ioctrl) throws IOException {
            try
            {
                while (buf.hasRemaining()) 
                {
                    //System.out.print(buf.get());
                    fos.write(buf.get());
                }
            }catch(Exception e)
            {
                System.out.println("[onCharReceived] Exception: " + e.getMessage());
            }
        }

        @Override
        protected void onCleanup() {
            try
            {             
                if(fos!=null)
                    fos.close();
            }catch(Exception e){
                System.out.println("[onCleanup] Exception: " + e.getMessage());         
            }
             System.out.println("onCleanup()");
        }

        @Override
        protected Boolean buildResult() {
            return Boolean.TRUE;
        }

    }
}

Errors:

URI Query: https://176.66.3.69:6443/download.aspx?Lang=EN&AuthToken=package
Aug 2, 2011 3:47:57 PM org.apache.http.impl.nio.client.NHttpClientProtocolHandler exception
SEVERE: I/O error: General SSLEngine problem
javax.net.ssl.SSLHandshakeException: General SSLEngine problem
    at com.sun.net.ssl.internal.ssl.Handshaker.checkThrown(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.checkTaskThrown(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.writeAppRecord(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.wrap(Unknown Source)
    at javax.net.ssl.SSLEngine.wrap(Unknown Source)
    at org.apache.http.impl.nio.reactor.SSLIOSession.doHandshake(SSLIOSession.java:154)
    at org.apache.http.impl.nio.reactor.SSLIOSession.isAppInputReady(SSLIOSession.java:276)
    at org.apache.http.impl.nio.client.InternalClientEventDispatch.inputReady(InternalClientEventDispatch.java:79)
    at org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:161)
    at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:335)
    at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:315)
    at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:275)
    at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104)
    at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:542)
    at java.lang.Thread.run(Unknown Source)
Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(Unknown Source)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
    at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
    at com.sun.net.ssl.internal.ssl.Handshaker$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.net.ssl.internal.ssl.Handshaker$DelegatedTask.run(Unknown Source)
    at org.apache.http.impl.nio.reactor.SSLIOSession.doHandshake(SSLIOSession.java:180)
    ... 9 more
Caused by: 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(Unknown Source)
    at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
    at sun.security.validator.Validator.validate(Unknown Source)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
    at com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(Unknown Source)
    ... 16 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
    at java.security.cert.CertPathBuilder.build(Unknown Source)
    ... 21 more
onCleanup()

[DownloadFile] Exception: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
Shutting down
Done

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(29

甜警司 2024-12-04 05:44:20

这解决了我的问题,

我们需要将证书导入本地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
        at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
        at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)

SSLPOKE 是一个工具,您可以在其中测试来自本地计算机的 https 连接。

测试连接的命令:

"%JAVA_HOME%/bin/java" SSLPoke <hostname> 443
    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:1496)
        at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
        at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026)
        at sun.security.ssl.Handshaker.process_record(Handshaker.java:961)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
        at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:747)
        at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:123)
        at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:138)
        at SSLPoke.main(SSLPoke.java:31)
    Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to 
    requested target
        at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
        at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
        at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
        ... 15 more
keytool -import -alias <anyname> -keystore "%JAVA_HOME%/jre/lib/security/cacerts" -file <cert path>

这将首先提示“输入密钥库密码:”changeit 是默认密码。最后提示“信任此证书?[否]:”,提供“是”将证书添加到密钥库。

验证:

C:\tools>"%JAVA_HOME%/bin/java" SSLPoke <hostname> 443
Successfully connected    

This solved my issue,

We need to import the cert onto the local java. If not we could get the below exception.

    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
        at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
        at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)

SSLPOKE is a tool where you can test the https connectivity from your local machine.

Command to test the connectivity:

"%JAVA_HOME%/bin/java" SSLPoke <hostname> 443
    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:1496)
        at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
        at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026)
        at sun.security.ssl.Handshaker.process_record(Handshaker.java:961)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
        at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:747)
        at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:123)
        at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:138)
        at SSLPoke.main(SSLPoke.java:31)
    Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to 
    requested target
        at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
        at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
        at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
        ... 15 more
keytool -import -alias <anyname> -keystore "%JAVA_HOME%/jre/lib/security/cacerts" -file <cert path>

this would first prompt to "Enter keystore password:" changeit is the default password. and finally a prompt "Trust this certificate? [no]:", provide "yes" to add the cert to keystore.

Verfication:

C:\tools>"%JAVA_HOME%/bin/java" SSLPoke <hostname> 443
Successfully connected    
甜妞爱困 2024-12-04 05:44:20

仅适用于 Windows,请按照以下步骤操作:

  1. 在 Chrome 中,转至设置。
  2. 在“设置”中单击“显示高级设置”。
  3. 在 HTTPS/SSL 下单击管理证书。
  4. 导出您的证书。
  5. 在 Windows 搜索中(按键盘上的 windows 键)键入 java.
  6. 选择(配置 Java)选项,该选项将打开 Java 控制面板
  7. 在 Java 控制面板中选择安全
  8. 选项卡 选择管理证书
  9. 单击
  10. 所选(用户)选项卡下的导入,证书类型为(受信任的证书)
  11. 单击导入按钮,浏览到下载的证书并将其导入。

For Windows only, follow these steps:

  1. In Chrome go to settings.
  2. In Settings click show advance settings.
  3. Under HTTPS/SSL Click on Manage Certificates.
  4. Export Your Certificate.
  5. In Windows searchs (Pressing windows key on keyboard) type java.
  6. Select (Configure Java) Option Which will open Java Control Panel
  7. Select Security tab in Java Control Panel
  8. Select Manage Certificates
  9. Click Import
  10. Under (User) tab selected and certificate type as (Trusted Certificates)
  11. Click import button and browse to downloaded certificate and import it.
幽梦紫曦~ 2024-12-04 05:44:20

我的 Apache 2.4 实例(使用 Comodo 通配符证书)上出现此错误的原因是 SHA-1 签名根证书的路径不完整。颁发的证书中有多个链,并且导致 SHA-1 根证书的链缺少 中间证书。现代浏览器知道如何处理这个问题,但 Java 7 默认情况下不处理它(尽管有一些复杂的方法可以在代码中完成此操作)。结果是错误消息看起来与自签名证书的情况相同:

Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380)
    ... 22 more

在这种情况下,由于缺少中间证书,会生成“无法找到请求目标的有效证书路径”消息。您可以使用 SSL Labs 对服务器进行测试来检查缺少哪个证书。找到适当的证书后,下载它并将其添加到证书包中(如果服务器在您的控制之下)。或者,您可以在本地导入缺少的证书。在服务器上解决此问题是解决该问题的更通用的方法。

The source of this error on my Apache 2.4 instance (using a Comodo wildcard certificate) was an incomplete path to the SHA-1 signed root certificate. There were multiple chains in the issued certificate, and the chain leading to a SHA-1 root certificate was missing an intermediate certificate. Modern browsers know how to handle this, but Java 7 doesn't handle it by default (although there are some convoluted ways to accomplish this in code). The result is error messages that look identical to the case of self-signed certificates:

Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380)
    ... 22 more

In this case, the "unable to find valid certification path to requested target" message is being produced due to the missing intermediate certificate. You can check which certificate is missing using SSL Labs test against the server. Once you find the appropriate certificate, download it and (if the server is under your control) add it to the certificate bundle. Alternatively, you can import the missing certificate locally. Accommodating this issue on the server is a more general solution to the problem.

被翻牌 2024-12-04 05:44:20

对于那些喜欢 Debian 和预打包 Java 的人:

sudo mkdir /usr/share/ca-certificates/test/  # don't mess with other certs
sudo cp ~/tmp/test.loc.crt /usr/share/ca-certificates/test/
sudo dpkg-reconfigure --force ca-certificates  # check your cert in curses GUI!
sudo update-ca-certificates --fresh --verbose

不要忘记检查 /etc/default/cacerts

# enable/disable updates of the keystore /etc/ssl/certs/java/cacerts
cacerts_updates=yes

要删除证书:

sudo rm /usr/share/ca-certificates/test/test.loc.crt
sudo rm /etc/ssl/certs/java/cacerts
sudo update-ca-certificates --fresh --verbose

For those who like Debian and prepackaged Java:

sudo mkdir /usr/share/ca-certificates/test/  # don't mess with other certs
sudo cp ~/tmp/test.loc.crt /usr/share/ca-certificates/test/
sudo dpkg-reconfigure --force ca-certificates  # check your cert in curses GUI!
sudo update-ca-certificates --fresh --verbose

Don't forget to check /etc/default/cacerts for:

# enable/disable updates of the keystore /etc/ssl/certs/java/cacerts
cacerts_updates=yes

To remove cert:

sudo rm /usr/share/ca-certificates/test/test.loc.crt
sudo rm /etc/ssl/certs/java/cacerts
sudo update-ca-certificates --fresh --verbose
抠脚大汉 2024-12-04 05:44:20

我只能使用代码让它工作,即不需要使用 keytool:

import com.netflix.config.DynamicBooleanProperty;
import com.netflix.config.DynamicIntProperty;
import com.netflix.config.DynamicPropertyFactory;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager;
import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
import org.apache.http.impl.nio.reactor.IOReactorConfig;
import org.apache.http.nio.conn.NoopIOSessionStrategy;
import org.apache.http.nio.conn.SchemeIOSessionStrategy;
import org.apache.http.nio.conn.ssl.SSLIOSessionStrategy;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import java.io.IOException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public class Test
{
    private static final DynamicIntProperty MAX_TOTAL_CONNECTIONS = DynamicPropertyFactory.getInstance().getIntProperty("X.total.connections", 40);
    private static final DynamicIntProperty ROUTE_CONNECTIONS = DynamicPropertyFactory.getInstance().getIntProperty("X.total.connections", 40);
    private static final DynamicIntProperty CONNECT_TIMEOUT = DynamicPropertyFactory.getInstance().getIntProperty("X.connect.timeout", 60000);
    private static final DynamicIntProperty SOCKET_TIMEOUT = DynamicPropertyFactory.getInstance().getIntProperty("X.socket.timeout", -1);
    private static final DynamicIntProperty CONNECTION_REQUEST_TIMEOUT = DynamicPropertyFactory.getInstance().getIntProperty("X.connectionrequest.timeout", 60000);
    private static final DynamicBooleanProperty STALE_CONNECTION_CHECK = DynamicPropertyFactory.getInstance().getBooleanProperty("X.checkconnection", true);

    public static void main(String[] args) throws Exception
    {

        SSLContext sslcontext = SSLContexts.custom()
                .useTLS()
                .loadTrustMaterial(null, new TrustStrategy()
                {
                    @Override
                    public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException
                    {
                        return true;
                    }
                })
                .build();
        SSLIOSessionStrategy sslSessionStrategy = new SSLIOSessionStrategy(sslcontext, new AllowAll());

        Registry<SchemeIOSessionStrategy> sessionStrategyRegistry = RegistryBuilder.<SchemeIOSessionStrategy>create()
                .register("http", NoopIOSessionStrategy.INSTANCE)
                .register("https", sslSessionStrategy)
                .build();

        DefaultConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(IOReactorConfig.DEFAULT);
        PoolingNHttpClientConnectionManager connectionManager = new PoolingNHttpClientConnectionManager(ioReactor, sessionStrategyRegistry);
        connectionManager.setMaxTotal(MAX_TOTAL_CONNECTIONS.get());
        connectionManager.setDefaultMaxPerRoute(ROUTE_CONNECTIONS.get());

        RequestConfig requestConfig = RequestConfig.custom()
                .setSocketTimeout(SOCKET_TIMEOUT.get())
                .setConnectTimeout(CONNECT_TIMEOUT.get())
                .setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT.get())
                .setStaleConnectionCheckEnabled(STALE_CONNECTION_CHECK.get())
                .build();

        CloseableHttpAsyncClient httpClient = HttpAsyncClients.custom()
                .setSSLStrategy(sslSessionStrategy)
                .setConnectionManager(connectionManager)
                .setDefaultRequestConfig(requestConfig)
                .build();

        httpClient.start();

        // use httpClient...
    }

    private static class AllowAll implements X509HostnameVerifier
    {
        @Override
        public void verify(String s, SSLSocket sslSocket) throws IOException
        {}

        @Override
        public void verify(String s, X509Certificate x509Certificate) throws SSLException {}

        @Override
        public void verify(String s, String[] strings, String[] strings2) throws SSLException
        {}

        @Override
        public boolean verify(String s, SSLSession sslSession)
        {
            return true;
        }
    }
}

I was able to get it working with code only, i.e. no need to use keytool:

import com.netflix.config.DynamicBooleanProperty;
import com.netflix.config.DynamicIntProperty;
import com.netflix.config.DynamicPropertyFactory;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager;
import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
import org.apache.http.impl.nio.reactor.IOReactorConfig;
import org.apache.http.nio.conn.NoopIOSessionStrategy;
import org.apache.http.nio.conn.SchemeIOSessionStrategy;
import org.apache.http.nio.conn.ssl.SSLIOSessionStrategy;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import java.io.IOException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public class Test
{
    private static final DynamicIntProperty MAX_TOTAL_CONNECTIONS = DynamicPropertyFactory.getInstance().getIntProperty("X.total.connections", 40);
    private static final DynamicIntProperty ROUTE_CONNECTIONS = DynamicPropertyFactory.getInstance().getIntProperty("X.total.connections", 40);
    private static final DynamicIntProperty CONNECT_TIMEOUT = DynamicPropertyFactory.getInstance().getIntProperty("X.connect.timeout", 60000);
    private static final DynamicIntProperty SOCKET_TIMEOUT = DynamicPropertyFactory.getInstance().getIntProperty("X.socket.timeout", -1);
    private static final DynamicIntProperty CONNECTION_REQUEST_TIMEOUT = DynamicPropertyFactory.getInstance().getIntProperty("X.connectionrequest.timeout", 60000);
    private static final DynamicBooleanProperty STALE_CONNECTION_CHECK = DynamicPropertyFactory.getInstance().getBooleanProperty("X.checkconnection", true);

    public static void main(String[] args) throws Exception
    {

        SSLContext sslcontext = SSLContexts.custom()
                .useTLS()
                .loadTrustMaterial(null, new TrustStrategy()
                {
                    @Override
                    public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException
                    {
                        return true;
                    }
                })
                .build();
        SSLIOSessionStrategy sslSessionStrategy = new SSLIOSessionStrategy(sslcontext, new AllowAll());

        Registry<SchemeIOSessionStrategy> sessionStrategyRegistry = RegistryBuilder.<SchemeIOSessionStrategy>create()
                .register("http", NoopIOSessionStrategy.INSTANCE)
                .register("https", sslSessionStrategy)
                .build();

        DefaultConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(IOReactorConfig.DEFAULT);
        PoolingNHttpClientConnectionManager connectionManager = new PoolingNHttpClientConnectionManager(ioReactor, sessionStrategyRegistry);
        connectionManager.setMaxTotal(MAX_TOTAL_CONNECTIONS.get());
        connectionManager.setDefaultMaxPerRoute(ROUTE_CONNECTIONS.get());

        RequestConfig requestConfig = RequestConfig.custom()
                .setSocketTimeout(SOCKET_TIMEOUT.get())
                .setConnectTimeout(CONNECT_TIMEOUT.get())
                .setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT.get())
                .setStaleConnectionCheckEnabled(STALE_CONNECTION_CHECK.get())
                .build();

        CloseableHttpAsyncClient httpClient = HttpAsyncClients.custom()
                .setSSLStrategy(sslSessionStrategy)
                .setConnectionManager(connectionManager)
                .setDefaultRequestConfig(requestConfig)
                .build();

        httpClient.start();

        // use httpClient...
    }

    private static class AllowAll implements X509HostnameVerifier
    {
        @Override
        public void verify(String s, SSLSocket sslSocket) throws IOException
        {}

        @Override
        public void verify(String s, X509Certificate x509Certificate) throws SSLException {}

        @Override
        public void verify(String s, String[] strings, String[] strings2) throws SSLException
        {}

        @Override
        public boolean verify(String s, SSLSession sslSession)
        {
            return true;
        }
    }
}
冰葑 2024-12-04 05:44:20

有很多方法可以解决这个问题...

一种方法是将 TrustStore 证书设置在密钥库文件中并将其放在应用程序的路径中,然后在 main 方法中设置这些系统属性:

public static void main(String[] args) {
  System.setProperty("javax.net.ssl.trustStore", "trust-store.jks");
  System.setProperty("javax.net.ssl.trustStorePassword", "TrustStore");
  ...
}

另一种方法是将密钥库放置为项目 jar 文件中的资源文件并加载它:

public static SSLContext createSSLContext(String resourcePath, String pass) throws NoSuchAlgorithmException, KeyStoreException, IOException, CertificateException, UnrecoverableKeyException, KeyManagementException {
  // initialise the keystore
  final char[] password = pass.toCharArray();
  KeyStore ks = KeyStore.getInstance("JKS");
  ks.load(ThisClass.class.getResourceAsStream(resourcePath
  ), password);

  // Setup the key manager factory.
  KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
  kmf.init(ks, password);

  // Setup the trust manager factory.
  TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
  tmf.init(ks);

  SSLContext sslc = SSLContext.getInstance("TLS");
  sslc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
  return sslc;
}

public static void main(String[] args) {
  SSLContext.setDefault(
    createSSLContext("/trust-store.jks", "TrustStore"));
  ...
}

在 Windows 中,您也可以尝试此解决方案: https://stackoverflow.com/a/59056537/980442


我从证书颁发机构 CA .crt 创建了密钥库文件 文件以这种方式:

keytool -import -alias ca -keystore trust-store.jks -storepass TrustStore -trustcacerts -file ca.crt

仅供参考:https://docs.oracle.com/javadb/10.8.3.0/adminguide/cadminsslclient .html

There is a lot of way to solve this...

One way is set the TrustStore certificates in a keystore file and put it in the path of the application, and set these system properties in the main method:

public static void main(String[] args) {
  System.setProperty("javax.net.ssl.trustStore", "trust-store.jks");
  System.setProperty("javax.net.ssl.trustStorePassword", "TrustStore");
  ...
}

Other way is place the keystore as resource file inside the project jar file and load it:

public static SSLContext createSSLContext(String resourcePath, String pass) throws NoSuchAlgorithmException, KeyStoreException, IOException, CertificateException, UnrecoverableKeyException, KeyManagementException {
  // initialise the keystore
  final char[] password = pass.toCharArray();
  KeyStore ks = KeyStore.getInstance("JKS");
  ks.load(ThisClass.class.getResourceAsStream(resourcePath
  ), password);

  // Setup the key manager factory.
  KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
  kmf.init(ks, password);

  // Setup the trust manager factory.
  TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
  tmf.init(ks);

  SSLContext sslc = SSLContext.getInstance("TLS");
  sslc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
  return sslc;
}

public static void main(String[] args) {
  SSLContext.setDefault(
    createSSLContext("/trust-store.jks", "TrustStore"));
  ...
}

In windows you can try this solution too: https://stackoverflow.com/a/59056537/980442


I created the keystore file from a Certificate authority CA .crt file in this way:

keytool -import -alias ca -keystore trust-store.jks -storepass TrustStore -trustcacerts -file ca.crt

FYI: https://docs.oracle.com/javadb/10.8.3.0/adminguide/cadminsslclient.html

七月上 2024-12-04 05:44:20

遇到了像这样的图片的问题。

输入图像描述这里

尝试了一些解决方案。
但发现即使是同一个项目,在别人的工作场所也完全没问题。无需额外设置。所以我们猜测这是一个环境问题。我们尝试更改 JDK 版本、IDE 但没有成功。调查花了大约4个小时,直到我们尝试了评分最高的答案。我没有找到该答案中提到的错误,但我通过浏览器发现有关 HTTP URL(锁定)的内容是 Charles 的认证。然后我意识到我的查尔斯一直在线。只要我把它关掉,它就一切正常。

所以我留下了我的经验,可能对你的案子有帮助。

Had the issue like this image.

enter image description here

Tried a few solutions.
But found that even if it's same project, when it's on other one's working place, it's totally fine. No extra settings needed. So we guessed it's an enviroment issue. We tried changing JDK version, IDE but didn't work. it took about 4 hours for investigation, until we tried the top-rated answer. I didn't find the error mentioned in that answer but I found via my browser about HTTP URL (lock) that there was a certification of Charles. Then I realized my charles was on all the time. As long as I turned that off, it's working all fine.

So I left my experience that could be helpful for your case.

只是在用心讲痛 2024-12-04 05:44:20

如果您在 2022 年来到这里并且使用的是 Mac,请按照此操作

1。下载证书。

echo -n | openssl s_client -connect <ServerName>:<PORT> -servername <ServerName> \
    | openssl x509 > /tmp/<ServerName>.cert

2.通过执行命令找到您的JDK路径。

/usr/libexec/java_home

3.现在将证书导入到jdk的cert-store中。

sudo keytool -import -alias mycertificate -keystore "<JDK_HOME>/lib/security/cacerts" -file /tmp/<ServerName>.cert

And if you are here in 2022 and are on mac follow this

1. Download the certificate.

echo -n | openssl s_client -connect <ServerName>:<PORT> -servername <ServerName> \
    | openssl x509 > /tmp/<ServerName>.cert

2. Find your JDK path by executing the command.

/usr/libexec/java_home

3. Now import the cert into the cert-store of jdk.

sudo keytool -import -alias mycertificate -keystore "<JDK_HOME>/lib/security/cacerts" -file /tmp/<ServerName>.cert
暗藏城府 2024-12-04 05:44:20

更新:重启有帮助是巧合(我希望如此,万岁!)。问题的真正原因是:当 Gradle 被指示使用特定密钥库时,该密钥库还必须包含所有官方根证书。否则它无法从常规存储库访问库。我必须做的是:

导入自签名证书:

keytool -import -trustcacerts -alias myselfsignedcert -file /Users/me/Desktop/selfsignedcert.crt -keystore ./privateKeystore.jks

添加官方根证书:

keytool -importkeystore -srckeystore <java-home>/lib/security/cacerts -destkeystore ./privateKeystore.jks

也许 Gradle 守护进程也妨碍了。如果事情开始看起来黯淡,可能值得杀死所有使用 ./gradlew --status 找到的正在运行的守护进程。

原始帖子:

没有人会相信这一点,我知道。不过,如果其他方法都失败了,请尝试一下:
重新启动我的 Mac 后,问题就消失了。咕噜。

背景:
./gradlew jar 一直给我“无法找到请求目标的有效证书路径”

我被困在自签名证书中,从浏览器保存,导入到 privateKeystore.jks 中。然后指示 Gradle 使用 privateKeystore.jks:

org.gradle.jvmargs=-Djavax.net.debug=SSL -Djavax.net.ssl.trustStore="/Users/me/IntelliJ/myproject/privateKeystore.jks"  -Djavax.net.ssl.trustStorePassword=changeit

如前所述,这仅在重新启动后才有效。

UPDATE: That a reboot helped was coincidental (I hoped so, hooray!). The real cause of the problem was this: When Gradle is directed to use a specific keystore, that keystore must also contain all the official root certificates. Otherwise it cannot access libraries from regular repositories. What I had to do was this:

Import the self-signed certificate:

keytool -import -trustcacerts -alias myselfsignedcert -file /Users/me/Desktop/selfsignedcert.crt -keystore ./privateKeystore.jks

Add the official root certificates:

keytool -importkeystore -srckeystore <java-home>/lib/security/cacerts -destkeystore ./privateKeystore.jks

Maybe the Gradle daemon also got in the way. Might be worth killing all running daemons found with ./gradlew --status if things start looking bleak.

ORIGINAL POSTING:

Nobody will believe this, I know. Still, if all else fails, give it a try:
After a reboot of my Mac the problem was gone. Grrr.

Background:
./gradlew jar kept giving me "unable to find valid certification path to requested target"

I am stuck with a self-signed certificate, saved from browser, imported in privateKeystore.jks. Then instructed Gradle to work with privateKeystore.jks:

org.gradle.jvmargs=-Djavax.net.debug=SSL -Djavax.net.ssl.trustStore="/Users/me/IntelliJ/myproject/privateKeystore.jks"  -Djavax.net.ssl.trustStorePassword=changeit

As mentioned, this only worked after a reboot.

小帐篷 2024-12-04 05:44:20

我遇到了与证书错误相同的问题,这是因为 SNI:我使用的 http 客户端没有实现 SNI。所以版本更新完成了这项工作

   <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.3.6</version>
    </dependency>

I had the same problem with the certificates error and it was because of SNI: the http client that I used didn't have SNI implemented. So a version update did the job

   <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.3.6</version>
    </dependency>
你是我的挚爱i 2024-12-04 05:44:20

这适用于您只需要安装 JDK 的任何操作系统:

  1. 从远程服务器下载证书:

    keytool -printcert -rfc -sslserver <您的远程服务器主机名> > /tmp/remorte-cert.crt

  2. 将证书导入到您的 JDK 密钥库:

    keytool -importcert -file /tmp/remorte-cert.crt -alias <远程服务器的别名> -storepass changeit -keystore " ${JAVA_HOME}/lib/security/cacerts" -noprompt

This works on any OS you just need JDK installed :

  1. Download the certificate from the remote server :

    keytool -printcert -rfc -sslserver <your remote server hostname> > /tmp/remorte-cert.crt

  2. Import the certificate to your JDK keystore :

    keytool -importcert -file /tmp/remorte-cert.crt -alias <an alias for your remote server> -storepass changeit -keystore "${JAVA_HOME}/lib/security/cacerts" -noprompt

游魂 2024-12-04 05:44:20

这也可能是由于将使用 SHA2 签名的 GoDaddy 证书与 Java 7 结合使用而导致的。

Chrome 和所有其他浏览器开始弃用使用 SHA1 签名的 SSL 证书,因为它不太安全。

有关该问题的更多信息可以找到此处,以及如何在您的服务器上解决该问题(如果您现在需要的话)。

This can also be caused by using GoDaddy certs with Java 7 that are signed using SHA2.

Chrome and all other browsers are starting to deprecate SSL certs that are signed using SHA1, as it's not as secure.

More info on the issue can be found here, as well as how to resolve it on your server if you need to now.

七度光 2024-12-04 05:44:20

AVG 版本 18.1.3044(使用 Windows 10)会干扰我的本地 Spring 应用程序。

解决方案:进入名为“Web 和电子邮件”的 AVG 部分并禁用“电子邮件保护”。
如果站点不安全,AVG 会阻止证书。

AVG version 18.1.3044 (with Windows 10) interfer with my local Spring application.

Solution: enter in AVG section called "Web and email" and disable the "email protection".
AVG block the certificate if the site isn't secure.

故人如初 2024-12-04 05:44:20
Download the certificate from Nexus3 Browser (click on the lock-pad for View Site Information in case of Edge broser)
Click on Connection is secure
Click on the certificate details
Click on Copy To file (it opens up export certificate wizard)
Choose Base-64 encoding
Browse and select a download location and file-name (let’s say mycert)
Open cmd
Goto the download location and execute the below command
keytool -import -alias mycert -keystore  "<<your-JAVA_HOME-directory>>\jre\lib\security\cacerts" -file mycert.cer
Restart the machine
Execute maven build again.
Download the certificate from Nexus3 Browser (click on the lock-pad for View Site Information in case of Edge broser)
Click on Connection is secure
Click on the certificate details
Click on Copy To file (it opens up export certificate wizard)
Choose Base-64 encoding
Browse and select a download location and file-name (let’s say mycert)
Open cmd
Goto the download location and execute the below command
keytool -import -alias mycert -keystore  "<<your-JAVA_HOME-directory>>\jre\lib\security\cacerts" -file mycert.cer
Restart the machine
Execute maven build again.
您的好友蓝忘机已上羡 2024-12-04 05:44:20

您有两个选择,将自签名证书导入到软件将运行的每个 jvm 的 java 密钥库中,或者尝试使用非验证 ssl 工厂:

jdbc:postgresql://myserver.com:5432/mydatabasename?ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory

You have two options, import the self-signed cert into java's keystore for each jvm the software will run on or try the non-validating ssl factory:

jdbc:postgresql://myserver.com:5432/mydatabasename?ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory
泛泛之交 2024-12-04 05:44:20

确保 https://176.66.3.69:6443/ 具有有效的证书。
您可以先通过浏览器查看https not secure如果它在浏览器中工作,它也会在 java 中工作。

这对我有用

Make sure that the https://176.66.3.69:6443/ have a valid certificate.
you can check it via browser firstly https not secureif it works in browser it will work in java.

that is working for me

日裸衫吸 2024-12-04 05:44:20

由于最初的问题是 - 如何忽略证书错误,这里是使用 SpringBoot 和 RestTemplate 的解决方案

@Service
public class SomeService {

    private final RestTemplate restTemplate;

    private final ObjectMapper objectMapper;    

    private static HttpComponentsClientHttpRequestFactory createRequestFactory() {
        try {
            SSLContextBuilder sslContext = new SSLContextBuilder();
            sslContext.loadTrustMaterial(null, new TrustAllStrategy());
            CloseableHttpClient client = HttpClients.custom().setSSLContext(sslContext.build()).setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).build();
            HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
            requestFactory.setHttpClient(client);
            return requestFactory;
        } catch (KeyManagementException | KeyStoreException | NoSuchAlgorithmException var3) {
            throw new IllegalStateException("Couldn't create HTTP Request factory ignore SSL cert validity: ", var3);
        }
    }

    @Autowired
    public SomeService(RestTemplate restTemplate, ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
        this.dimetorURL = dimetorURL;
        restTemplate.setRequestFactory(createRequestFactory());
    }


    public ResponseEntity<ResponseObject> sendRequest(RequestObject requestObject) {
        //...
        return restTemplate.exchange(url, HttpMethod.GET, ResponseObject.class);
        //...
    }
}

As original question was - how to ignore the cert error, here is solution for those using SpringBoot and RestTemplate

@Service
public class SomeService {

    private final RestTemplate restTemplate;

    private final ObjectMapper objectMapper;    

    private static HttpComponentsClientHttpRequestFactory createRequestFactory() {
        try {
            SSLContextBuilder sslContext = new SSLContextBuilder();
            sslContext.loadTrustMaterial(null, new TrustAllStrategy());
            CloseableHttpClient client = HttpClients.custom().setSSLContext(sslContext.build()).setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).build();
            HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
            requestFactory.setHttpClient(client);
            return requestFactory;
        } catch (KeyManagementException | KeyStoreException | NoSuchAlgorithmException var3) {
            throw new IllegalStateException("Couldn't create HTTP Request factory ignore SSL cert validity: ", var3);
        }
    }

    @Autowired
    public SomeService(RestTemplate restTemplate, ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
        this.dimetorURL = dimetorURL;
        restTemplate.setRequestFactory(createRequestFactory());
    }


    public ResponseEntity<ResponseObject> sendRequest(RequestObject requestObject) {
        //...
        return restTemplate.exchange(url, HttpMethod.GET, ResponseObject.class);
        //...
    }
}
假情假意假温柔 2024-12-04 05:44:20

如果在 maven 或使用 TestNG 的 maven 中出现此错误:

  1. 从目标网站下载证书并在您的计算机上安装证书(使用上面建议的 keytool 或在 Windows 上),
  2. 将以下内容添加到 maven 参数(命令行和/或IDE):
    -Djavax.net.ssl.trustStore=C:\Users\me.keystore -Djavax.net.ssl.trustStorePassword=X
    其中 X 是您在 keytool 步骤中使用的密码。

注意:C:\Users\me.keystore 也应该设置为与您的计算机相匹配。
例如 :

mvn -ea -Dtestng.dtd.http=true  -Djavax.net.ssl.trustStore=C:\Users\me\.keystore -Djavax.net.ssl.trustStorePassword=X -Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true -Dmaven.wagon.http.ssl.ignore.validity.dates=true -Dcucumber.features=src/test/resources -Dcucumber.glue=com.myapp -Dcucumber.filter.tags="@MY_TEST"

If getting this error in maven, or maven with TestNG :

  1. download the certificate from the target website and install certificate on your machine (using keytool as suggested above, or on windows)
  2. add the following content to the maven arguments (command line and/or IDE):
    -Djavax.net.ssl.trustStore=C:\Users\me.keystore -Djavax.net.ssl.trustStorePassword=X
    Where X is the password you used at the keytool step.

note : C:\Users\me.keystore should also be set to match your machine.
For instance :

mvn -ea -Dtestng.dtd.http=true  -Djavax.net.ssl.trustStore=C:\Users\me\.keystore -Djavax.net.ssl.trustStorePassword=X -Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true -Dmaven.wagon.http.ssl.ignore.validity.dates=true -Dcucumber.features=src/test/resources -Dcucumber.glue=com.myapp -Dcucumber.filter.tags="@MY_TEST"
櫻之舞 2024-12-04 05:44:20

就我而言,我正在运行带有 Java 1.6 的 MacOs High Sierra。 cacert 文件所在的位置与上面 Gabe Martin-Dempesy 的答案中引用的位置不同。 cacert 文件也已链接到另一个位置 (/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/security/cacerts)。

我使用 FireFox 将证书从相关网站导出到名为“exportedCertFile.crt”的本地文件。从那里,我使用 keytool 将证书移动到 cacert 文件中。这解决了问题。

bash-3.2# cd /Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/security/
bash-3.2# keytool -importcert -file ~/exportedCertFile.crt -alias example -keystore cacerts -storepass changeit

In my case I'm running MacOs High Sierra with Java 1.6. The cacert file is in a different location than referenced above in Gabe Martin-Dempesy's answer. The cacert file was also already linked to another location (/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/security/cacerts).

Using FireFox, I exported the certificate from the web site in question to a local file called "exportedCertFile.crt". From there, I used keytool to move the certificate into the cacert file. This fixed the problem.

bash-3.2# cd /Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/security/
bash-3.2# keytool -importcert -file ~/exportedCertFile.crt -alias example -keystore cacerts -storepass changeit
愿得七秒忆 2024-12-04 05:44:20

首先下载 ssl 证书,然后您可以转到 java bin 路径,在控制台中执行以下命令。

C:\java\JDK1.8.0_66-X64\bin>keytool -printcert -file C:\Users\lova\openapi.cer -keystore openapistore

first Download the ssl certificate then you can go to your java bin path execute the below command in the console.

C:\java\JDK1.8.0_66-X64\bin>keytool -printcert -file C:\Users\lova\openapi.cer -keystore openapistore
止于盛夏 2024-12-04 05:44:20

就我而言,我的密钥库和信任库都具有相同的证书,因此删除信任库会有所帮助。有时,如果您有多个证书副本,证书链可能会成为问题。

In my case I had both keystore and truststore having the same certificate so removing truststore helped. Sometimes the chain of certificates can be an issue if you've multiple copies of certificates.

酷炫老祖宗 2024-12-04 05:44:20

这就是我在 macOS 上的工作方式。将服务器名称和服务器端口替换为您自己的。

在终端上运行这两个命令。

从远程服务器下载证书

openssl x509 -in <(openssl s_client -connect server-name:server-port -prexit 2>/dev/null) -out ~/server-name.crt

将证书导入 Java 密钥库

sudo keytool -importcert -file ~/server-name.crt -alias server-name -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit

重新启动您的应用程序,证书错误就会消失!

This is what worked for me on macOS. Replace server-name and server-port with your own.

Run these two commands on your terminal.

Download certificate from the remote server

openssl x509 -in <(openssl s_client -connect server-name:server-port -prexit 2>/dev/null) -out ~/server-name.crt

Import cert to Java keystore

sudo keytool -importcert -file ~/server-name.crt -alias server-name -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit

Restart your application and the certs errors should go away!

北陌 2024-12-04 05:44:19

当您的服务器具有自签名证书时,就会出现此问题。要解决此问题,您可以将此证书添加到 JVM 的受信任证书列表中。

在本文中作者介绍了如何从浏览器获取证书并添加将其复制到 JVM 的 cacerts 文件中。您可以编辑 JAVA_HOME/jre/lib/security/cacerts 文件或使用 -Djavax.net.ssl.trustStore 参数运行应用程序。验证您也使用哪个 JDK/JRE,因为这通常会造成混乱。

另请参阅:SSL 是怎样的证书服务器名称已解析/我可以使用 keytool 添加备用名称吗? 如果遇到 java.security.cert.CertificateException: No namematching localhostfound 异常。

The problem appears when your server has self signed certificate. To workaround it you can add this certificate to the list of trusted certificates of your JVM.

In this article author describes how to fetch the certificate from your browser and add it to cacerts file of your JVM. You can either edit JAVA_HOME/jre/lib/security/cacerts file or run you application with -Djavax.net.ssl.trustStore parameter. Verify which JDK/JRE you are using too as this is often a source of confusion.

See also: How are SSL certificate server names resolved/Can I add alternative names using keytool? If you run into java.security.cert.CertificateException: No name matching localhost found exception.

2024-12-04 05:44:19

以下是在 ma​​cOS 上对我可靠有效的方法。确保将 example.com 和 443 替换为您尝试连接的实际主机名和端口,并提供自定义别名。第一个命令从远程服务器下载提供的证书并将其以 x509 格式保存在本地。第二个命令将保存的证书加载到 Java 的 SSL 信任存储中。

openssl x509 -in <(openssl s_client -connect example.com:443 -prexit 2>/dev/null) -out ~/example.crt
sudo keytool -importcert -file ~/example.crt -alias example -keystore $(/usr/libexec/java_home)/jre/lib/security/cacerts -storepass changeit

Windows 下通过 Git Bash 或 WSL 第一个命令看起来有点不同:

openssl s_client -connect git.css.ch:443  -prexit > ~/cert.txt
openssl x509 -in ~/cert.txt -out ~/example.crt

Here's what reliably works for me on macOS. Make sure to replace example.com and 443 with the actual hostname and port you're trying to connect to, and give a custom alias. The first command downloads the provided certificate from the remote server and saves it locally in x509 format. The second command loads the saved certificate into Java's SSL trust store.

openssl x509 -in <(openssl s_client -connect example.com:443 -prexit 2>/dev/null) -out ~/example.crt
sudo keytool -importcert -file ~/example.crt -alias example -keystore $(/usr/libexec/java_home)/jre/lib/security/cacerts -storepass changeit

Under Windows via Git Bash or WSL the first command looks a bit different :

openssl s_client -connect git.css.ch:443  -prexit > ~/cert.txt
openssl x509 -in ~/cert.txt -out ~/example.crt
画▽骨i 2024-12-04 05:44:19
  1. 使用 Firefox 导出 SSL 证书。您可以通过在浏览器中点击 URL 来导出它,然后选择导出证书的选项。假设证书文件名为 your.ssl.server.name.crt
  2. 转到您的 JRE_HOME/binJDK/JRE/bin
  3. 类型命令
  4. keytool -keystore ..\lib\security\cacerts -import -alias your.ssl.server.name -file .\relative-path-to-cert-file\your.ssl.server.name.crt
  5. 重新启动 Java 进程
  1. Export the SSL certificate using Firefox. You can export it by hitting the URL in the browser and then select the option to export the certificate. Let's assume the cert file name is your.ssl.server.name.crt
  2. Go to your JRE_HOME/bin or JDK/JRE/bin
  3. Type the command
  4. keytool -keystore ..\lib\security\cacerts -import -alias your.ssl.server.name -file .\relative-path-to-cert-file\your.ssl.server.name.crt
  5. Restart your Java process
爱人如己 2024-12-04 05:44:19

我对来自 symantec 的有效签名通配符证书也有同样的问题。

首先尝试使用 -Djavax.net.debug=SSL 运行 Java 应用程序,看看到底发生了什么。

我最终导入了中间证书,这导致证书链中断。

我从 symantec 下载了丢失的中间证书(您可以在 ssl 握手日志中看到丢失证书的下载链接:http在我的例子中为://svrintl-g3-aia.verisign.com/SVRIntlG3.cer)。

我在 java 密钥库中导入了证书。导入中间证书后,我的通配符 ssl 证书终于开始工作:

keytool -import -keystore ../jre/lib/security/cacerts -trustcacerts -alias "VeriSign Class 3 International Server CA - G3" -file /pathto/SVRIntlG3.cer

I had the same issue with a valid signed wildcard certificate from symantec.

First try running your java application with -Djavax.net.debug=SSL to see what is really going on.

I ended up importing the intermediate certificate which was causing the cert chain to break.

I downloaded the missing intermediate cert from symantec (you can see the download link to the missing cert in the ssl handshake log: http://svrintl-g3-aia.verisign.com/SVRIntlG3.cer in my case).

And I imported the cert in the java keystore. After importing the intermediate certificate my wildcard ssl cert finally started working:

keytool -import -keystore ../jre/lib/security/cacerts -trustcacerts -alias "VeriSign Class 3 International Server CA - G3" -file /pathto/SVRIntlG3.cer
鸠魁 2024-12-04 05:44:19

@Gabe Martin-Dempesy 的回答对我有帮助。我写了一个与之相关的小脚本。使用方法非常简单。

从主机安装证书:

> sudo ./java-cert-importer.sh example.com

删除已安装的证书。

> sudo ./java-cert-importer.sh example.com --delete

java-cert-importer.sh

#!/usr/bin/env bash

# Exit on error
set -e

# Ensure script is running as root
if [ "$EUID" -ne 0 ]
  then echo "WARN: Please run as root (sudo)"
  exit 1
fi

# Check required commands
command -v openssl >/dev/null 2>&1 || { echo "Required command 'openssl' not installed. Aborting." >&2; exit 1; }
command -v keytool >/dev/null 2>&1 || { echo "Required command 'keytool' not installed. Aborting." >&2; exit 1; }

# Get command line args
host=$1; port=${2:-443}; deleteCmd=${3:-${2}}

# Check host argument
if [ ! ${host} ]; then
cat << EOF
Please enter required parameter(s)

usage:  ./java-cert-importer.sh <host> [ <port> | default=443 ] [ -d | --delete ]

EOF
exit 1
fi;

if [ "$JAVA_HOME" ]; then
    javahome=${JAVA_HOME}
elif [[ "$OSTYPE" == "linux-gnu" ]]; then # Linux
    javahome=$(readlink -f $(which java) | sed "s:bin/java::")
elif [[ "$OSTYPE" == "darwin"* ]]; then # Mac OS X
    javahome="$(/usr/libexec/java_home)/jre"
fi

if [ ! "$javahome" ]; then
    echo "WARN: Java home cannot be found."
    exit 1
elif [ ! -d "$javahome" ]; then
    echo "WARN: Detected Java home does not exists: $javahome"
    exit 1
fi

echo "Detected Java Home: $javahome"

# Set cacerts file path
cacertspath=${javahome}/lib/security/cacerts
cacertsbackup="${cacertspath}.$.backup"

if ( [ "$deleteCmd" == "-d" ] || [ "$deleteCmd" == "--delete" ] ); then
    sudo keytool -delete -alias ${host} -keystore ${cacertspath} -storepass changeit
    echo "Certificate is deleted for ${host}"
    exit 0
fi

# Get host info from user
#read -p "Enter server host (E.g. example.com) : " host
#read -p "Enter server port (Default 443) : " port

# create temp file
tmpfile="/tmp/${host}.$.crt"

# Create java cacerts backup file
cp ${cacertspath} ${cacertsbackup}

echo "Java CaCerts Backup: ${cacertsbackup}"

# Get certificate from speficied host
openssl x509 -in <(openssl s_client -connect ${host}:${port} -prexit 2>/dev/null) -out ${tmpfile}

# Import certificate into java cacerts file
sudo keytool -importcert -file ${tmpfile} -alias ${host} -keystore ${cacertspath} -storepass changeit

# Remove temp certificate file
rm ${tmpfile}

# Check certificate alias name (same with host) that imported successfully
result=$(keytool -list -v -keystore ${cacertspath} -storepass changeit | grep "Alias name: ${host}")

# Show results to user
if [ "$result" ]; then
    echo "Success: Certificate is imported to java cacerts for ${host}";
else
    echo "Error: Something went wrong";
fi;

@Gabe Martin-Dempesy's answer is helped to me. And I wrote a small script related to it. The usage is very simple.

Install a certificate from host:

> sudo ./java-cert-importer.sh example.com

Remove the certificate that installed already.

> sudo ./java-cert-importer.sh example.com --delete

java-cert-importer.sh

#!/usr/bin/env bash

# Exit on error
set -e

# Ensure script is running as root
if [ "$EUID" -ne 0 ]
  then echo "WARN: Please run as root (sudo)"
  exit 1
fi

# Check required commands
command -v openssl >/dev/null 2>&1 || { echo "Required command 'openssl' not installed. Aborting." >&2; exit 1; }
command -v keytool >/dev/null 2>&1 || { echo "Required command 'keytool' not installed. Aborting." >&2; exit 1; }

# Get command line args
host=$1; port=${2:-443}; deleteCmd=${3:-${2}}

# Check host argument
if [ ! ${host} ]; then
cat << EOF
Please enter required parameter(s)

usage:  ./java-cert-importer.sh <host> [ <port> | default=443 ] [ -d | --delete ]

EOF
exit 1
fi;

if [ "$JAVA_HOME" ]; then
    javahome=${JAVA_HOME}
elif [[ "$OSTYPE" == "linux-gnu" ]]; then # Linux
    javahome=$(readlink -f $(which java) | sed "s:bin/java::")
elif [[ "$OSTYPE" == "darwin"* ]]; then # Mac OS X
    javahome="$(/usr/libexec/java_home)/jre"
fi

if [ ! "$javahome" ]; then
    echo "WARN: Java home cannot be found."
    exit 1
elif [ ! -d "$javahome" ]; then
    echo "WARN: Detected Java home does not exists: $javahome"
    exit 1
fi

echo "Detected Java Home: $javahome"

# Set cacerts file path
cacertspath=${javahome}/lib/security/cacerts
cacertsbackup="${cacertspath}.$.backup"

if ( [ "$deleteCmd" == "-d" ] || [ "$deleteCmd" == "--delete" ] ); then
    sudo keytool -delete -alias ${host} -keystore ${cacertspath} -storepass changeit
    echo "Certificate is deleted for ${host}"
    exit 0
fi

# Get host info from user
#read -p "Enter server host (E.g. example.com) : " host
#read -p "Enter server port (Default 443) : " port

# create temp file
tmpfile="/tmp/${host}.$.crt"

# Create java cacerts backup file
cp ${cacertspath} ${cacertsbackup}

echo "Java CaCerts Backup: ${cacertsbackup}"

# Get certificate from speficied host
openssl x509 -in <(openssl s_client -connect ${host}:${port} -prexit 2>/dev/null) -out ${tmpfile}

# Import certificate into java cacerts file
sudo keytool -importcert -file ${tmpfile} -alias ${host} -keystore ${cacertspath} -storepass changeit

# Remove temp certificate file
rm ${tmpfile}

# Check certificate alias name (same with host) that imported successfully
result=$(keytool -list -v -keystore ${cacertspath} -storepass changeit | grep "Alias name: ${host}")

# Show results to user
if [ "$result" ]; then
    echo "Success: Certificate is imported to java cacerts for ${host}";
else
    echo "Error: Something went wrong";
fi;
半夏半凉 2024-12-04 05:44:19

引用自 不再有“无法”找到请求目标的有效证书路径'

尝试使用 JSSE 打开与主机的 SSL 连接时。这通常意味着服务器正在使用测试证书(可能使用 keytool 生成),而不是来自知名商业证书颁发机构(例如 Verisign 或 GoDaddy)的证书。在这种情况下,Web 浏览器会显示警告对话框,但由于 JSSE 无法假设存在交互式用户,因此默认情况下只会引发异常。

证书验证是 SSL 安全的一个非常重要的部分,但我写这篇文章并不是为了解释细节。如果您有兴趣,可以从阅读维基百科简介开始。我编写此条目是为了展示一种使用测试证书与该主机通信的简单方法(如果您确实愿意的话)。

基本上,您希望将服务器的证书与受信任的证书一起添加到 KeyStore

请尝试此处提供的代码。这可能有帮助。

Quoting from No more 'unable to find valid certification path to requested target'

when trying to open an SSL connection to a host using JSSE. What this usually means is that the server is using a test certificate (possibly generated using keytool) rather than a certificate from a well known commercial Certification Authority such as Verisign or GoDaddy. Web browsers display warning dialogs in this case, but since JSSE cannot assume an interactive user is present it just throws an exception by default.

Certificate validation is a very important part of SSL security, but I am not writing this entry to explain the details. If you are interested, you can start by reading the Wikipedia blurb. I am writing this entry to show a simple way to talk to that host with the test certificate, if you really want to.

Basically, you want to add the server's certificate to the KeyStore with your trusted certificates

Try the code provided there. It might help.

红玫瑰 2024-12-04 05:44:19

我遵循的简单步骤。

问题:我尝试连接到端点(https://%s.blob.core.windows .net)使用一个简单的java类(main方法)。

所以我在问题中遇到了上面提到的认证问题。

解决方案:

  1. 使用浏览器(chrome)获取证书。为此,请将您的端点 URL 粘贴到浏览器中并输入。现在您将看到一个锁定图标,单击该图标-->证书-->详情-->复制到文件-->下载它。

  2. 以管理员身份打开 cmd(我使用的是 Windows),然后导航到您下载 .cer 文件的目录。

3.(可选)如果您在同一台计算机中使用多个 JDK,则将 JDK 版本更改为与应用程序中使用的版本相同。

  1. 现在使用以下命令

keytool -import -alias mycertificate -keystore "C:\Program
文件\Java\jdk-11.0.5\lib\security\cacerts”-文件myurlcrt.cer

  1. 给出默认密码:changeit

  2. 信任此证书:yes

,您就完成了。

谢谢!

Simple Steps that I followed.

problem: I was trying to connect to an endpoint(https://%s.blob.core.windows.net) using a simple java class(main method).

So I was getting this certification issue as mentioned above, in the question.

Solution:

  1. Get the certificate using a browser(chrome). To do this paste your endpoint URL in the browser and enter. Now you will see a lock icon, click on that -->certificate--> details --> copy to files--> download it.

  2. open the cmd(i am using windows) as admin and then navigate to the directory where you have downloaded the .cer file.

3.(Optional)If you are using multiple JDK in the same machine then change your JDK version the same as you are using in your application.

  1. Now use the below command

keytool -import -alias mycertificate -keystore "C:\Program
Files\Java\jdk-11.0.5\lib\security\cacerts" -file myurlcrt.cer

  1. Give the default password: changeit

  2. Trust this certificate: yes

And you are done.

Thanks!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文