如何解决javax.net.ssl.SSLHandshakeException错误?

我连接到VPN来设置库存API来获取产品清单,它工作正常。 一旦我从Web服务获得结果,并绑定到UI。 而且我还将PayPal与我的应用程序进行了快速结账,当我拨打付款电话时,我正面临着这个错误。 我使用servlet进行后端进程。 任何人都可以说如何解决这个问题?

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 

首先,您需要从您尝试连接的服务器获取公共证书。 这可以通过多种方式来完成,例如联系服务器pipe理员并询问它, 使用openssl下载 ,或者由于这看起来是HTTP服务器,可以通过任何浏览器连接到它,查看页面的安全信息并保存证书的副本。 (谷歌应该能够准确地告诉你为特定的浏览器做些什么。)

现在您已将证书保存在文件中,您需要将其添加到JVM的信任存储中。 在$JAVA_HOME/jre/lib/security/对于JRE或对于JDK来说$JAVA_HOME/lib/security ,有一个名为cacerts的文件,它随Java一起提供,并包含着名authentication机构的公用证书。 要导入新证书,请以有权写入cacerts的用户身份运行keytool:

 keytool -import -file <the cert file> -alias <some meaningful name> -keystore <path to cacerts file> 

它很可能会问你一个密码。 与java一起提供的默认密码是changeit 。 几乎没有人改变它。 完成这些相对简单的步骤之后,您将安全地进行通信,并确保您正在与正确的服务器通信,并且只有正确的服务器(只要不丢失其私钥)。

现在我用这种方式解决了这个问题,

 import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import java.io.OutputStream; // Create a trust manager that does not validate certificate chains like the default TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) { //No need to implement. } public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) { //No need to implement. } } }; // Install the all-trusting trust manager try { SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); } catch (Exception e) { System.out.println(e); } 

当然,这个解决scheme只能用于那些无法使用keytool安装所需的证书的场景,例如使用临时证书进行本地testing。

每当我们尝试连接到URL,

如果其他站点上的服务器使用https协议运行,并且要求我们通过证书中提供的信息进行通信,那么我们有以下选项:

1)询问证书(下载证书),在trustore中导入这个证书。 默认的java使用的trustore可以在\ Java \ jdk1.6.0_29 \ jre \ lib \ security \ cacerts中find,那么如果我们重试连接到URL连接就会被接受。

2)在正常的商业案例中,我们可能会连接到组织内部的URL,我们知道他们是正确的。 在这种情况下,您可以相信这是正确的URL。在上述情况下,可以使用不需要存储证书以连接到特定URL的代码。

对于第二点,我们必须遵循以下步骤:

1)在下面写下为HttpsURLConnection设置HostnameVerifier的方法,该方法返回true,表示我们正在信任trustStore。

  // trusting all certificate public void doTrustToCertificates() throws Exception { Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider()); TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return null; } public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException { return; } public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException { return; } } }; SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); HostnameVerifier hv = new HostnameVerifier() { public boolean verify(String urlHostName, SSLSession session) { if (!urlHostName.equalsIgnoreCase(session.getPeerHost())) { System.out.println("Warning: URL host '" + urlHostName + "' is different to SSLSession host '" + session.getPeerHost() + "'."); } return true; } }; HttpsURLConnection.setDefaultHostnameVerifier(hv); } 

2)写下面的方法,在尝试连接到URL之前调用doTrustToCertificates

  // connecting to URL public void connectToUrl(){ doTrustToCertificates();// URL url = new URL("https://www.example.com"); HttpURLConnection conn = (HttpURLConnection)url.openConnection(); System.out.println("ResponseCode ="+conn.getResponseCode()); } 

此调用将返回响应代码= 200意味着连接成功。

有关更多详细信息和示例示例,可以参考URL 。

我相信你正在尝试连接到一些使用SSL的东西,但是某些东西提供了一个证书,这个证书没有被诸如verisign这样的根证书颁发机构validation。实质上,默认情况下,安全连接只能在连接的人知道交易对手钥匙或Verisign等其他软件都可以插入,并说所提供的公钥确实是对的。

所有操作系统的信任less数authentication机构和小型证书颁发者需要通过一个authentication链,如果你明白我的意思是由一个大型authentication机构authentication…

无论如何回到这一点..编程一个Java小程序和一个Java服务器时,我有一个类似的问题(希望有一天,我会写一个完整的博文,关于我如何得到所有的安全工作:))

实际上,我所要做的就是从服务器提取公钥并将其存储在我的小程序中的密钥库中,并且当我连接到服务器时,我使用此密钥存储创build信任工厂,并且信任工厂创buildssl连接。 还有更改过程,例如将密钥添加到JVM的可信主机,并在启动时修改默认的信任库。

我做了这个两个月左右,现在没有我的源代码..使用谷歌,你应该能够解决这个问题。 如果你不能回复我,我可以提供相关的项目相关的源代码..不知道这是否解决了你的问题,因为你没有提供导致这些exception的代码。 此外,我正在与小程序工作,我不明白为什么它不会在Serverlets上工作…

PS我无法获得周末前,因为外部SSH在我的办公室被禁用:(

SSLHandshakeException可以通过2种方式解决。

  1. 合并SSL

    • 获取SSL(通过询问源系统pipe理员,也可以通过openssl命令下载,或者任何浏览器下载证书)

    • 将证书添加到位于JRE / lib / security的信任库(cacerts)

    • 在vm参数中提供truststore位置为“-Djavax.net.ssl.trustStore =”

  2. 忽略SSL

    对于这#2,请访问我的另一个stackoverflow网站上的其他答案: 如何ingore SSLvalidation 忽略Java证书错误与Java

请通过这篇文章了解问题并解决这个问题: https ://blog.mindorks.com/handle-ssl-https-certification-path-exception-for-java-applications-1b13c751f1e7

现在我用这种方式解决了这个问题,

 import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import java.io.OutputStream; // Create a trust manager that does not validate certificate chains like the default TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) { //No need to implement. } public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) { //No need to implement. } } }; // Install the all-trusting trust manager try { SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); } catch (Exception e) { System.out.println(e); }