首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何绕过java中的ssl证书检查

如何绕过java中的ssl证书检查
EN

Stack Overflow用户
提问于 2017-03-15 10:14:08
回答 4查看 98K关注 0票数 18

我希望访问托管在远程vm中的具有https的url。在使用HttpURLConnection访问它时,我得到了一个异常。

这是我的密码:

代码语言:javascript
运行
复制
import javax.net.ssl.*;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

/**
 * Created by prasantabiswas on 07/03/17.
 */
public class Main
{
    public static void main(String [] args)
    {
        try
        {
            URL url = new URL("https://myhost:8913/myservice/service?wsdl");
            HttpURLConnection http = null;

            if (url.getProtocol().toLowerCase().equals("https")) {
                trustAllHosts();
                HttpsURLConnection https = (HttpsURLConnection) url.openConnection();
                https.setHostnameVerifier(DO_NOT_VERIFY);
                http = https;
            } else {
                http = (HttpURLConnection) url.openConnection();
            }
            String SOAPAction="";
//            http.setRequestProperty("Content-Length", String.valueOf(b.length));
            http.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
            http.setRequestProperty("SOAPAction", SOAPAction);
            http.setRequestMethod("GET");
            http.setDoOutput(true);
            http.setDoInput(true);
            OutputStream out = http.getOutputStream();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };

    private static void trustAllHosts() {
        // Create a trust manager that does not validate certificate chains
        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return new java.security.cert.X509Certificate[] {};
            }

            public void checkClientTrusted(X509Certificate[] chain,
                                           String authType) throws CertificateException
            {
            }

            public void checkServerTrusted(X509Certificate[] chain,
                                           String authType) throws CertificateException {
            }
        } };

        // 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) {
            e.printStackTrace();
        }
    }
}

我得到了以下例外:

代码语言:javascript
运行
复制
javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: Certificates does not conform to algorithm constraints
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1509)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1283)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1258)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:250)
    at Main.main(Main.java:35)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: java.security.cert.CertificateException: Certificates does not conform to algorithm constraints
    at sun.security.ssl.AbstractTrustManagerWrapper.checkAlgorithmConstraints(SSLContextImpl.java:1055)
    at sun.security.ssl.AbstractTrustManagerWrapper.checkAdditionalTrust(SSLContextImpl.java:981)
    at sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(SSLContextImpl.java:923)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1491)
    ... 18 more

尝试了与谷歌搜索不同的解决方案,但都没有奏效。我想避免使用keytool,因为我将在不同的vm上运行我的测试。

有谁能解决这个问题吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-11-01 08:30:45

使用X509ExtendedTrustManager而不是X509TrustManager()解决了这个问题。下面是一个例子:

代码语言:javascript
运行
复制
public void trustAllHosts()
    {
        try
        {
            TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509ExtendedTrustManager()
                    {
                        @Override
                        public java.security.cert.X509Certificate[] getAcceptedIssuers()
                        {
                            return null;
                        }

                        @Override
                        public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
                        {
                        }

                        @Override
                        public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)
                        {
                        }

                        @Override
                        public void checkClientTrusted(java.security.cert.X509Certificate[] xcs, String string, Socket socket) throws CertificateException
                        {

                        }

                        @Override
                        public void checkServerTrusted(java.security.cert.X509Certificate[] xcs, String string, Socket socket) throws CertificateException
                        {

                        }

                        @Override
                        public void checkClientTrusted(java.security.cert.X509Certificate[] xcs, String string, SSLEngine ssle) throws CertificateException
                        {

                        }

                        @Override
                        public void checkServerTrusted(java.security.cert.X509Certificate[] xcs, String string, SSLEngine ssle) throws CertificateException
                        {

                        }

                    }
            };

            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

            // Create all-trusting host name verifier
            HostnameVerifier allHostsValid = new  HostnameVerifier()
            {
                @Override
                public boolean verify(String hostname, SSLSession session)
                {
                    return true;
                }
            };
            // Install the all-trusting host verifier
            HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
        }
        catch (Exception e)
        {
            log.error("Error occurred",e);
        }
    }
票数 26
EN

Stack Overflow用户

发布于 2017-03-15 10:33:38

编辑:理解在使用它之前会造成的漏洞。这绝不是推荐用于生产用途的。

最好的方法是创建一个信任一切的虚拟信任管理器。

代码语言:javascript
运行
复制
 TrustManager[] dummyTrustManager = new TrustManager[] { new X509TrustManager() {
      public java.security.cert.X509Certificate[] getAcceptedIssuers() {
        return null;
      }

      public void checkClientTrusted(X509Certificate[] certs, String authType) {
      }

      public void checkServerTrusted(X509Certificate[] certs, String authType) {
      }
    } };

然后使用虚拟信任管理器初始化SSL上下文。

代码语言:javascript
运行
复制
SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, dummyTrustManager, new java.security.SecureRandom());

最后,使用SSLContext打开连接

代码语言:javascript
运行
复制
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

    URL url = new URL("https://myhost:8913/myservice/service?wsdl");

这个问题已经在这里得到了更详细的回答,Java:禁用SSL证书检查的重写功能

更新:

以上问题是由于Java不支持证书签名算法造成的。根据这个职位,Java8的后续版本已经禁用了md5算法。

要启用md5支持,请在/lib/security下找到java.security文件,并定位行(535)

代码语言:javascript
运行
复制
jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, 

并删除MD5

票数 7
EN

Stack Overflow用户

发布于 2017-03-15 10:32:20

尝试使用Apache客户端,这对我是有效的。

代码语言:javascript
运行
复制
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustStrategy() {
     public boolean isTrusted(final X509Certificate[] chain, String authType) throws CertificateException {
          return true;
     }
});
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build());

CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();

// GET or POST request with the client
...
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42806709

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档