Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么可以';我找不到SSL握手的信任库?_Java_Spring_Tomcat_Rest_Ssl - Fatal编程技术网

Java 为什么可以';我找不到SSL握手的信任库?

Java 为什么可以';我找不到SSL握手的信任库?,java,spring,tomcat,rest,ssl,Java,Spring,Tomcat,Rest,Ssl,我在客户端使用SpringRESTTemplate调用REST端点。本例中的客户端是Spring应用程序,Tomcat是servlet容器 我在连接HTTPS端点时遇到问题。我收到一个错误,表明它找不到信任库的有效路径。我在哪里可以指定这个?这是在容器级别还是在应用程序配置(Spring)级别完成的 堆栈跟踪: org.springframework.web.client.ResourceAccessException: I/O error: sun.security.validator.Val

我在客户端使用SpringRESTTemplate调用REST端点。本例中的客户端是Spring应用程序,Tomcat是servlet容器

我在连接HTTPS端点时遇到问题。我收到一个错误,表明它找不到信任库的有效路径。我在哪里可以指定这个?这是在容器级别还是在应用程序配置(Spring)级别完成的

堆栈跟踪:

org.springframework.web.client.ResourceAccessException: I/O error:
sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target;
nested exception is 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
org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:330)
org.springframework.web.client.RestTemplate.execute(RestTemplate.java:292)
org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:227)

您需要正确配置SSLContext,这是在RESTTemplate外部完成的。这应该让你开始:

    String keystoreType = "JKS";
    InputStream keystoreLocation = null;
    char [] keystorePassword = null;
    char [] keyPassword = null;

    KeyStore keystore = KeyStore.getInstance(keystoreType);
    keystore.load(keystoreLocation, keystorePassword);
    KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    kmfactory.init(keystore, keyPassword);

    InputStream truststoreLocation = null;
    char [] truststorePassword = null;
    String truststoreType = "JKS";

    KeyStore truststore = KeyStore.getInstance(truststoreType);
    truststore.load(truststoreLocation, truststorePassword);
    TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());

    KeyManager [] keymanagers = kmfactory.getKeyManagers();
    TrustManager [] trustmanagers =  tmfactory.getTrustManagers();

    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(keymanagers, trustmanagers, new SecureRandom());
    SSLContext.setDefault(sslContext);

更具体地说,调用此方法将实现此目的,因此任何后续的HttpClient调用都不会关心SSL证书的有效性:

public static void trustSelfSignedSSL() {
    try {
        SSLContext ctx = SSLContext.getInstance("TLS");
        X509TrustManager tm = new X509TrustManager() {

            public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {
            }

            public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {
            }

            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };
        ctx.init(null, new TrustManager[]{tm}, null);
        SSLContext.setDefault(ctx);
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

您可以在任何地方编写它,因为它对SSLContext类本身进行静态调用。只要您在相同的类加载器上下文中调用它,并且在第一次HttpClient调用之前,您就可以开始了?所以每次启动应用程序时都需要这样做。作为参考,我必须导入以下内容才能使用此。。。导入javax.net.ssl.SSLContext;导入javax.net.ssl.X509TrustManager;导入java.security.cert.x509证书;导入javax.net.ssl.TrustManager;导入java.security.cert.CertificateException;