为什么我找不到SSL握手的信任库?

我在客户端使用Spring RESTTemplate来调用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) 

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

  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(); } }