当前位置: 首页 > 面试题库 >

用Java URL连接完全忽略ssl的简单方法是什么?

洪照
2023-03-14
问题内容

我正在构建一个应用程序,该应用程序会定期检查一些rss
feed中的新内容。这些提要中的某些只能通过https访问,而有些则具有自签名或证书破损。我希望能够继续检查它们。

请注意,此应用程序中的安全性不是问题,其目标是以最小的努力访问内容。

我正在使用以下代码来规避大多数证书问题:

/**
     * 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;
    }

这适用于大多数站点,但是在一个站点上我仍然遇到此异常:

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)

有谁知道我该如何解决?


问题答案:

有一个解决方案,在这里它优雅地为我工作。刚打电话

SSLUtilities.trustAllHostnames();
SSLUtilities.trustAllHttpsCertificates();

在进行SSL连接之前。

您还可以通过在Internet上搜索来获取更多解决方案java ssl trustall

这是该解决方案的副本(以防将来链接可能断开):

 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


 类似资料:
  • 问题内容: 我本质上是在寻找“ @Ignore”类型注释,通过它我可以阻止特定字段的持久化。如何做到这一点? 问题答案: 符合您的需求。

  • 问题内容: 我正在使用几个Kafka连接器,但在控制台输出中看不到它们的创建/部署中的任何错误,但是我没有得到想要的结果(无论是任何结果,无论是期望的还是除此以外)。我基于Kafka的示例FileStream连接器制作了这些连接器,因此我的调试技术基于该示例中使用的SLF4J Logger的使用。我搜索了我认为会在控制台输出中产生的日志消息,但无济于事。我在这些消息中找错了地方吗?还是有调试这些连

  • 为什么如果我将这个简单的谓词赋给'func'而不是(在我的情况下总是false),我会在忽略条件时获得所有元素,而不是获得0个元素呢? 我想是因为谓词中没有考虑SettingItemModel对象,但我不确定。

  • 问题内容: 我使用Spring-Data Neo4j 2.2.0-RELEASE。(我的以下问题将适用于任何其他类型的实体映射,为什么不适用于JPA) 在我的项目中,我有一个用Spring注释注释的公共方法,因为我想在其中更新/保存一个实体: 我的application-context.xml是以下内容: 正如我们在此配置中看到的,aspectJ用于事务。 因此,我尝试通过更改applicatio

  • 我在 AWS S3 中备份了以下文件,这些文件由 Kafka 连接接收器连接器备份: 当使用Kafka connect S3源恢复主题时,密钥文件被忽略,我在日志中看到以下调试消息: 我的源配置如下所示: 我应该做什么改变才能让密钥和消息一起存储在Kafka中?

  • 问题内容: 我正在尝试从另一个站点获取信息。当我尝试去做 它抛出一个。这是否意味着该站点将不允许自动连接?还有另一种获取此信息的方法吗? 问题答案: 这可能意味着几件事: 该站点有问题并且正在主动断开连接(拒绝与超时不同,拒绝完全没有响应) 中间人可能拒绝了您的连接,例如防火墙,尽管如果您可以通过浏览器访问该站点,则不太可能 您使用了错误的端口,即您输入https://时的意思是http://,反