证书不符合算法约束。仅在连接到第二台服务器且仅与Java 1.8.144连接时。为什么呢?

时间:2018-02-14 11:37:22

标签: java ssl-certificate jax-ws apache-httpclient-4.x

我有一个通过SSL连接到SAP系统的应用程序。该应用程序使用JAX-WS(用于Web服务调用)和Apache HttPComponent 4.5.3用于所有其他SSL调用。除非我使用Java 1.8 131或144运行应用程序,否则一切正常。我得到以下异常:

  

javax.net.ssl.SSLHandshakeException:
       java.security.cert.CertificateException:证书不符合
      算法约束       在sun.security.ssl.Alerts.getSSLException(未知来源)       at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)       在sun.security.ssl.Handshaker.fatalSE(未知来源)       在sun.security.ssl.Handshaker.fatalSE(未知来源)       at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)       在sun.security.ssl.ClientHandshaker.processMessage(未知来源)       在sun.security.ssl.Handshaker.processLoop(未知来源)       在sun.security.ssl.Handshaker.process_record(未知来源)       at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)       at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)       在sun.security.ssl.SSLSocketImpl.startHandshake(未知来源)       在sun.security.ssl.SSLSocketImpl.startHandshake(未知来源)       引起:java.security.cert.CertificateException:       证书不符合
的算法约束       security.ssl.AbstractTrustManagerWrapper.checkAlgorithmConstraints(不明       在
      security.ssl.AbstractTrustManagerWrapper.checkAdditionalTrust(未知       在       sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(未知

我已阅读java.security.cert.CertificateException: Certificates does not conform to algorithm constraints,但它并不适用于我的案例,因为......

  1. 连接到SAP服务器1时,一切正常
  2. 之后连接到SAP Server 2时(也通过SSL)我得到"证书不符合"错误
  3. 当我颠倒序列并首先连接到SAP Server 2时,一切正常
  4. 但是当我连接到SAP服务器1(之前有效)时,我得到了同样的错误
  5. 这个问题只发生在Java 1.8 131和144上。它适用于1.7和Java 1.8.121
  6. 所有这些向我表明,根本原因不是证书和密码的问题,但在Java 1.8.144中混合使用JAX-WS和Apache HTTPS调用时会出现问题

    这是用于禁用JAX-WS的SSL检查的代码(基于https://log.rowanto.com/java-8-turning-off-ssl-certificate-check/):

    public static final void disableCertificateValidationForWebServices() {
        // Create a trust manager that does not validate certificate chains
    
        TrustManager[] trustAllCerts = new TrustManager[] {
    new X509ExtendedTrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] 
    

    x509Certificates,String s){             }

            @Override
            public void checkServerTrusted(X509Certificate[] 
    

    x509Certificates,String s){             }

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
    
            @Override
            public void checkClientTrusted(X509Certificate[] 
                x509Certificates, String s, Socket socket) {
            }
    
            @Override
            public void checkServerTrusted(X509Certificate[] 
                x509Certificates, String s, Socket socket) {
            }
    
            @Override
            public void checkClientTrusted(X509Certificate[] 
                 x509Certificates, String s, SSLEngine sslEngine) {
            }
    
            @Override
            public void checkServerTrusted(X509Certificate[] 
               x509Certificates, String s, SSLEngine sslEngine) {
            }
        } };
    
        // Install the all-trusting trust manager
        try {
            final SSLContext sc = SSLContext.getInstance("SSL"); // or TLS?
            sc.init(null, trustAllCerts, new SecureRandom());     
     HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
           .setDefaultHostnameVerifier(NoopHostnameVerifier.INSTANCE);      } catch (Exception e) {
        }
    }
    

    这是用于禁用Apache HTTPS调用的SSL检查的代码(基于http://stackoverflow.com/questions/22606579/apache-httpclient-4-3-and-x509-client-certificate-to-authenticate):

    public static SSLConnectionSocketFactory getInstance() {
    
        if (instance == null) {
            Log.info("Disabling SSL Certificate Checks");
    
            final SSLContextBuilder builder = SSLContexts.custom();
            // here in the loadTrustMaterial the SSL Provider is loaded.
    
            try {
                builder.loadTrustMaterial(null, new TrustStrategy() {
                    @Override
                    public boolean isTrusted(X509Certificate[] arg0, String 
      arg1) {
                        return true;
                    }
    
                });
    
                final SSLContext sslContext = builder.build();
    
                instance = new SSLConnectionSocketFactory(sslContext, 
       NoopHostnameVerifier.INSTANCE);
            } catch (NoSuchAlgorithmException e) {
                Log.error("disableCertificateValidation() failed with 
      NoSuchAlgorithmException. Detail message:", e);
                listTrustManagers(null);
            } catch (KeyStoreException e) {
                Log.error("disableCertificateValidation() failed with 
     KeyStoreException. Detail message: ", e);
                listTrustManagers(null);
            } catch (KeyManagementException e) {
                Log.error("disableCertificateValidation() failed with 
      KeyManagementException. Detail message: ", e);
            }
    
        }
        return instance;
    }
    

    是的,我们正在使用PoolingConnectionManager:

    public final class MyPoolingHttpClientConnectionManager {
    
    private static PoolingHttpClientConnectionManager instance = null;
    
    private final static Object LOCK = new Object();
    
    protected MyPoolingHttpClientConnectionManager() {
        // Exists only to defeat instantiation.
    }
    
    public static PoolingHttpClientConnectionManager getInstance() {
        synchronized (LOCK) {
            if (instance == null) {
                instance = new 
    PoolingHttpClientConnectionManager(disableCertificateValidation());
                // Increase max total connection to 50
                instance.setMaxTotal(50);
                // Increase default max connection per route to 20
                instance.setDefaultMaxPerRoute(20);
    
            }
        }
        return instance;
    }
    
    /*
     * This is called when we create the HTTPConnectionPool
     * 
     * 
     */
    private final static Registry<ConnectionSocketFactory> 
    disableCertificateValidation() {
        return RegistryBuilder.<ConnectionSocketFactory>
    create().register("https", MySSLContext.getInstance())
                .register("http", new 
     PlainConnectionSocketFactory()).build();
    
    }
    

    }

    非常欢迎任何想法

1 个答案:

答案 0 :(得分:-1)

安装Java 1.8 161解决了这个问题。似乎是131版本中的Java错误,最多151个。