用java url连接完全忽略ssl的简单方法是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21257455/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Whats an easy way to totally ignore ssl with java url connections?
提问by samy
I'm building an application that periodically checks some rss feeds for new content. Some of these feeds are only reachable via https and some have self signed or somehow broken certificates. I want to be able to check them never the less.
我正在构建一个应用程序,它会定期检查一些 RSS 提要以获取新内容。其中一些提要只能通过 https 访问,而一些提要具有自签名或以某种方式损坏的证书。我希望能够检查它们。
Please note that security is not an issue in this application the goal is to access the content with minimal effort.
请注意,此应用程序中的安全性不是问题,目标是以最少的努力访问内容。
I'm using this code to circumvent most of the certificate issues:
我正在使用此代码来规避大多数证书问题:
/**
* Sets timeout values and user agent header, and ignores self signed ssl
* certificates to enable maximum coverage
*
* @param con
* @return
*/
public static URLConnection configureConnection(URLConnection con)
{
con.setRequestProperty(
"User-Agent",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11");
con.setConnectTimeout(30000);
con.setReadTimeout(40000);
if (con instanceof HttpsURLConnection)
{
HttpsURLConnection conHttps = (HttpsURLConnection) con;
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager()
{
public java.security.cert.X509Certificate[] getAcceptedIssuers()
{
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType)
{
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType)
{
}
} };
HostnameVerifier allHostsValid = new HostnameVerifier()
{
@Override
public boolean verify(String arg0, SSLSession arg1)
{
return true;
}
};
// Install the all-trusting trust manager
try
{
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc
.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
con = conHttps;
} catch (Exception e)
{
}
}
return con;
}
this works for most of the sites, but on one I still get this exception:
这适用于大多数网站,但在一个网站上我仍然遇到此异常:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification pat
h to requested target
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1715)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:257)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:251)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1168)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:609)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:545)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:963)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1208)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1235)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1219)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:440)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1139)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:397)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:338)
at crawler.RSSReader.getNewArticles(RSSReader.java:53)
at crawler.Crawler.fetchFeed(Crawler.java:187)
at crawler.Crawler.main(Crawler.java:120)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:622)
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
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(PKIXValidator.java:324)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:224)
at sun.security.validator.Validator.validate(Validator.java:235)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:147)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:230)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:270)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1147)
... 20 more
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:197)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:255)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:319)
Does anyone know how I can resolve this?
有谁知道我该如何解决这个问题?
采纳答案by Yasser Zamani
There is a solution at herewhich gracefully works for me. Just call
有一个解决方案,在这里它优雅地为我工作。打电话就行
SSLUtilities.trustAllHostnames();
SSLUtilities.trustAllHttpsCertificates();
Before your SSL connection.
在您的 SSL 连接之前。
You can also capture more solution by searching Internet for java ssl trustall
.
您还可以通过在 Internet 上搜索java ssl trustall
.
Here is the copy of that solution (in case of maybe a broken link in future):
这是该解决方案的副本(以防将来链接断开):
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
/**
* This class provide various static methods that relax X509 certificate and
* hostname verification while using the SSL over the HTTP protocol.
*
* @author Francis Labrie
*/
public final class SSLUtilities {
/**
* Hostname verifier for the Sun's deprecated API.
*
* @deprecated see {@link #_hostnameVerifier}.
*/
private static com.sun.net.ssl.HostnameVerifier __hostnameVerifier;
/**
* Thrust managers for the Sun's deprecated API.
*
* @deprecated see {@link #_trustManagers}.
*/
private static com.sun.net.ssl.TrustManager[] __trustManagers;
/**
* Hostname verifier.
*/
private static HostnameVerifier _hostnameVerifier;
/**
* Thrust managers.
*/
private static TrustManager[] _trustManagers;
/**
* Set the default Hostname Verifier to an instance of a fake class that
* trust all hostnames. This method uses the old deprecated API from the
* com.sun.ssl package.
*
* @deprecated see {@link #_trustAllHostnames()}.
*/
private static void __trustAllHostnames() {
// Create a trust manager that does not validate certificate chains
if(__hostnameVerifier == null) {
__hostnameVerifier = new _FakeHostnameVerifier();
} // if
// Install the all-trusting host name verifier
com.sun.net.ssl.HttpsURLConnection.
setDefaultHostnameVerifier(__hostnameVerifier);
} // __trustAllHttpsCertificates
/**
* Set the default X509 Trust Manager to an instance of a fake class that
* trust all certificates, even the self-signed ones. This method uses the
* old deprecated API from the com.sun.ssl package.
*
* @deprecated see {@link #_trustAllHttpsCertificates()}.
*/
private static void __trustAllHttpsCertificates() {
com.sun.net.ssl.SSLContext context;
// Create a trust manager that does not validate certificate chains
if(__trustManagers == null) {
__trustManagers = new com.sun.net.ssl.TrustManager[]
{new _FakeX509TrustManager()};
} // if
// Install the all-trusting trust manager
try {
context = com.sun.net.ssl.SSLContext.getInstance("SSL");
context.init(null, __trustManagers, new SecureRandom());
} catch(GeneralSecurityException gse) {
throw new IllegalStateException(gse.getMessage());
} // catch
com.sun.net.ssl.HttpsURLConnection.
setDefaultSSLSocketFactory(context.getSocketFactory());
} // __trustAllHttpsCertificates
/**
* Return true if the protocol handler property java.
* protocol.handler.pkgs is set to the Sun's com.sun.net.ssl.
* internal.www.protocol deprecated one, false
* otherwise.
*
* @return true if the protocol handler
* property is set to the Sun's deprecated one, false
* otherwise.
*/
private static boolean isDeprecatedSSLProtocol() {
return("com.sun.net.ssl.internal.www.protocol".equals(System.
getProperty("java.protocol.handler.pkgs")));
} // isDeprecatedSSLProtocol
/**
* Set the default Hostname Verifier to an instance of a fake class that
* trust all hostnames.
*/
private static void _trustAllHostnames() {
// Create a trust manager that does not validate certificate chains
if(_hostnameVerifier == null) {
_hostnameVerifier = new FakeHostnameVerifier();
} // if
// Install the all-trusting host name verifier:
HttpsURLConnection.setDefaultHostnameVerifier(_hostnameVerifier);
} // _trustAllHttpsCertificates
/**
* Set the default X509 Trust Manager to an instance of a fake class that
* trust all certificates, even the self-signed ones.
*/
private static void _trustAllHttpsCertificates() {
SSLContext context;
// Create a trust manager that does not validate certificate chains
if(_trustManagers == null) {
_trustManagers = new TrustManager[] {new FakeX509TrustManager()};
} // if
// Install the all-trusting trust manager:
try {
context = SSLContext.getInstance("SSL");
context.init(null, _trustManagers, new SecureRandom());
} catch(GeneralSecurityException gse) {
throw new IllegalStateException(gse.getMessage());
} // catch
HttpsURLConnection.setDefaultSSLSocketFactory(context.
getSocketFactory());
} // _trustAllHttpsCertificates
/**
* Set the default Hostname Verifier to an instance of a fake class that
* trust all hostnames.
*/
public static void trustAllHostnames() {
// Is the deprecated protocol setted?
if(isDeprecatedSSLProtocol()) {
__trustAllHostnames();
} else {
_trustAllHostnames();
} // else
} // trustAllHostnames
/**
* Set the default X509 Trust Manager to an instance of a fake class that
* trust all certificates, even the self-signed ones.
*/
public static void trustAllHttpsCertificates() {
// Is the deprecated protocol setted?
if(isDeprecatedSSLProtocol()) {
__trustAllHttpsCertificates();
} else {
_trustAllHttpsCertificates();
} // else
} // trustAllHttpsCertificates
/**
* This class implements a fake hostname verificator, trusting any host
* name. This class uses the old deprecated API from the com.sun.
* ssl package.
*
* @author Francis Labrie
*
* @deprecated see {@link SSLUtilities.FakeHostnameVerifier}.
*/
public static class _FakeHostnameVerifier
implements com.sun.net.ssl.HostnameVerifier {
/**
* Always return true, indicating that the host name is an
* acceptable match with the server's authentication scheme.
*
* @param hostname the host name.
* @param session the SSL session used on the connection to
* host.
* @return the true boolean value
* indicating the host name is trusted.
*/
public boolean verify(String hostname, String session) {
return(true);
} // verify
} // _FakeHostnameVerifier
/**
* This class allow any X509 certificates to be used to authenticate the
* remote side of a secure socket, including self-signed certificates. This
* class uses the old deprecated API from the com.sun.ssl
* package.
*
* @author Francis Labrie
*
* @deprecated see {@link SSLUtilities.FakeX509TrustManager}.
*/
public static class _FakeX509TrustManager
implements com.sun.net.ssl.X509TrustManager {
/**
* Empty array of certificate authority certificates.
*/
private static final X509Certificate[] _AcceptedIssuers =
new X509Certificate[] {};
/**
* Always return true, trusting for client SSL
* chain peer certificate chain.
*
* @param chain the peer certificate chain.
* @return the true boolean value
* indicating the chain is trusted.
*/
public boolean isClientTrusted(X509Certificate[] chain) {
return(true);
} // checkClientTrusted
/**
* Always return true, trusting for server SSL
* chain peer certificate chain.
*
* @param chain the peer certificate chain.
* @return the true boolean value
* indicating the chain is trusted.
*/
public boolean isServerTrusted(X509Certificate[] chain) {
return(true);
} // checkServerTrusted
/**
* Return an empty array of certificate authority certificates which
* are trusted for authenticating peers.
*
* @return a empty array of issuer certificates.
*/
public X509Certificate[] getAcceptedIssuers() {
return(_AcceptedIssuers);
} // getAcceptedIssuers
} // _FakeX509TrustManager
/**
* This class implements a fake hostname verificator, trusting any host
* name.
*
* @author Francis Labrie
*/
public static class FakeHostnameVerifier implements HostnameVerifier {
/**
* Always return true, indicating that the host name is
* an acceptable match with the server's authentication scheme.
*
* @param hostname the host name.
* @param session the SSL session used on the connection to
* host.
* @return the true boolean value
* indicating the host name is trusted.
*/
public boolean verify(String hostname,
javax.net.ssl.SSLSession session) {
return(true);
} // verify
} // FakeHostnameVerifier
/**
* This class allow any X509 certificates to be used to authenticate the
* remote side of a secure socket, including self-signed certificates.
*
* @author Francis Labrie
*/
public static class FakeX509TrustManager implements X509TrustManager {
/**
* Empty array of certificate authority certificates.
*/
private static final X509Certificate[] _AcceptedIssuers =
new X509Certificate[] {};
/**
* Always trust for client SSL chain peer certificate
* chain with any authType authentication types.
*
* @param chain the peer certificate chain.
* @param authType the authentication type based on the client
* certificate.
*/
public void checkClientTrusted(X509Certificate[] chain,
String authType) {
} // checkClientTrusted
/**
* Always trust for server SSL chain peer certificate
* chain with any authType exchange algorithm types.
*
* @param chain the peer certificate chain.
* @param authType the key exchange algorithm used.
*/
public void checkServerTrusted(X509Certificate[] chain,
String authType) {
} // checkServerTrusted
/**
* Return an empty array of certificate authority certificates which
* are trusted for authenticating peers.
*
* @return a empty array of issuer certificates.
*/
public X509Certificate[] getAcceptedIssuers() {
return(_AcceptedIssuers);
} // getAcceptedIssuers
} // FakeX509TrustManager
} // SSLUtilities