SSLHandshakeException可以通过两种方法解决。
我已与VPN连接,以设置广告资源API来获取产品列表,并且效果很好。一旦我从Web服务获得结果并绑定到UI。当我遇到付款错误时,我也将PayPal与我的make Express结帐应用程序集成在一起。我将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
首先,您需要从尝试连接的服务器获取公共证书。这可以通过多种方式完成,例如联系服务器管理员并要求输入using OpenSSL to download it,或者由于这似乎是HTTP服务器,因此可以通过任何浏览器连接到该服务器,查看页面的安全信息,以及保存证书的副本。 (Google应该能够准确告诉您如何使用特定的浏览器。)
现在您已将证书保存在文件中,您需要将其添加到JVM的信任库中。 JRE的$JAVA_HOME/jre/lib/security/
或JDK的$JAVA_HOME/lib/security
处有一个名为cacerts
的文件,该文件随Java一起提供,其中包含著名的证书颁发机构的公共证书。要导入新证书,请以具有写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);
}
当然,此解决方案仅应在无法使用keytool
安装所需证书的情况下使用,例如使用临时证书进行本地测试。
[只要我们尝试连接到URL,
如果另一个站点的服务器正在运行https协议,并要求我们通过证书中提供的信息进行通信,则我们有以下选择:
1)索取证书(下载证书),并以trustore的形式导入此证书。可以在\ Java \ jdk1.6.0_29 \ jre \ lib \ security \ cacerts中找到默认的trustore Java使用,然后如果我们重试连接到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连接到某物,但某物所提供的证书未经root证书颁发机构(如verisign)验证。本质上,默认情况下,只有在试图连接某人的情况下,才能建立安全连接connect知道交易对手的密钥或诸如verisign之类的其他供应商可以介入,并说所提供的公钥确实是正确的。
ALL OS信任少数证书颁发机构,并且较小的证书颁发者需要由大型认证机构之一进行认证,如果您理解我的意思,那么该认证机构将组成一系列认证机构...
无论如何,现在回到了这一点。在编写Java小程序和Java服务器时,我遇到了类似的问题(希望有一天,我会写一篇完整的博文,介绍如何使所有安全性发挥作用:))]
[本质上,我要做的是从服务器中提取公共密钥,并将其存储在我的applet内的密钥库中,当我连接到服务器时,我使用此密钥库创建了一个信任工厂,并使用了该信任工厂来创建ssl连接。还有一些备用过程,例如将密钥添加到JVM的受信任主机,并在启动时修改默认信任库。
我大约两个月前做了这个,现在没有源代码。使用google,您应该可以解决此问题。如果您不能给我回信,并且我可以为您提供该项目的相关事件源代码,则不知道这是否可以解决您的问题,因为您没有提供导致这些异常的代码。此外,我正在使用applet进行工作,以为我看不到为什么它无法在Serverlets上运行...
P.S我无法在周末之前获取源代码,因为我的办公室已禁用外部SSH:(
SSLHandshakeException可以通过两种方法解决。
并入SSL
获取SSL(通过询问源系统管理员,也可以由openssl命令下载,或任何浏览器下载证书)
将证书添加到位于以下位置的信任库(证书)中JRE / lib / security
在vm参数中提供信任库位置为“ -Djavax.net.ssl.trustStore =”
忽略SSL
对于此#2,请在另一个stackoverflow网站上访问我的其他答案:How to ingore SSL verification Ignore SSL Certificate Errors with Java
现在我以这种方式解决了这个问题,
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);
}
SSLHandshakeException可以通过两种方法解决。
现在我以这种方式解决了这个问题,