0

Hana Cloud Platform Javaアプリケーションの外部でRESTfulサービスを利用しています。アプリケーションJEE6プロファイルおよびその他のHCPライブラリの一部として提供されているApache HttpClient(v4.1.3)を介して、HCPで設定したこれらの宛先と対話できます。HCP JEE6サーバーがTLS 1.0をサポートしていない場合、宛先のあるアプリケーションが失敗する

インテグレーションインフラストラクチャのベンダー最近TLSv1.0に接続していますが、それ以降はRESTサービスに接続しようとするとエラーが発生します。

これはスタックトレースです:

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated 
at sun.security.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:421) 
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128) 
at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:397) 
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:148) 
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:150) 
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:121) 
at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:575) 
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:425) 
at com.sap.core.connectivity.httpdestination.client.RequestDirectorExtender.execute(RequestDirectorExtender.java:47) 
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820) 
at com.sap.core.connectivity.httpdestination.impl.AbstractHttpClientWrapper$2.execute(AbstractHttpClientWrapper.java:141) 
at com.sap.core.connectivity.httpdestination.impl.AbstractHttpClientWrapper$2.execute(AbstractHttpClientWrapper.java:1) 
at com.sap.core.connectivity.httpdestination.impl.AbstractHttpClientWrapper.executeOperation(AbstractHttpClientWrapper.java:300) 
at com.sap.core.connectivity.httpdestination.impl.AbstractHttpClientWrapper.execute(AbstractHttpClientWrapper.java:277) 
at com.sap.core.connectivity.httpdestination.impl.AbstractHttpClientWrapper.execute(AbstractHttpClientWrapper.java:132) 
at com.sap.core.connectivity.httpdestination.impl.AbstractHttpClientWrapper.execute(AbstractHttpClientWrapper.java:126) 
at my.domain.hcp.HttpRequestSupport.service(HttpRequestSupport.java:124) 
at my.domain.gap.proxy.ProxyServlet.service(ProxyServlet.java:36) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
at com.sap.core.communication.server.CertValidatorFilter.doFilter(CertValidatorFilter.java:156) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:218) 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) 
at org.eclipse.virgo.web.enterprise.security.valve.OpenEjbSecurityInitializationValve.invoke(OpenEjbSecurityInitializationValve.java:44) 
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:614) 
at com.sap.core.jpaas.security.auth.service.lib.AbstractAuthenticator.invoke(AbstractAuthenticator.java:170) 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169) 
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956) 
at com.sap.core.tenant.valve.TenantValidationValve.invokeNextValve(TenantValidationValve.java:168) 
at com.sap.core.tenant.valve.TenantValidationValve.invoke(TenantValidationValve.java:94) 
at com.sap.js.statistics.tomcat.valve.RequestTracingValve.invoke(RequestTracingValve.java:38) 
at com.sap.core.js.monitoring.tomcat.valve.RequestTracingValve.invoke(RequestTracingValve.java:27) 
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) 
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:442) 
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1083) 
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:640) 
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
at java.lang.Thread.run(Thread.java:807) 

我々はTLSv1.1またはTLSv1.2を使用するように強制し、TLSv1.0を使用しないようにJavaアプリケーションにJVM引数を追加しようとしている:

-Dhttps.protocols=TLSv1.1,TLSv1.2 

JVM引数を設定すると何も起こりません。Apache HttpClientライブラリがこの設定を無視するようです。 Apache HttpClient(v4.1.3)をTLSの新しいバージョンに強制するもう1つの方法はありますか?

+0

私は誰かがこれを便利に思うかもしれないので、私はここに投稿しています。この優れたツールを使用して、TLSプロトコルの問題が特定されました。https://www.ssllabs.com/ssltest/analyze.html – juanheyns

答えて

0

org.apache.http.conn.ssl.SSLSocketFactoryクラスを拡張し、それをHttpClientに登録して、クライアントに特定のプロトコルを使用させることができることが判明しました。

private static final String CA_CERTS_PATH = System.getProperties().getProperty("java.home") + File.separator + 
     "lib" + File.separator + "security" + File.separator + "cacerts"; 

private HttpClient createHttpClient(HttpDestination httpDestination) 
     throws DestinationException, KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, KeyManagementException { 

    HttpClient httpClient = httpDestination.createHttpClient(); 
    try (FileInputStream fis = new FileInputStream(CA_CERTS_PATH)) { 
     KeyStore keyStore = KeyStore.getInstance("JKS"); 
     keyStore.load(fis, "changeit".toCharArray()); 

     TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
     tmf.init(keyStore); 

     SSLContext ctx = SSLContext.getInstance("TLS"); 
     ctx.init(null, tmf.getTrustManagers(), new SecureRandom()); 

     // Instantiate the custom SSLSocketFactory 
     SSLSocketFactory sslSocketFactory = new CustomSSLSocketFactory(
       ctx, 
       SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER, 
       new String[]{"TLSv1.1", "TLSv1.2"} 
     ); 

     // Register the https scheme with the custom SSLSocketFactory 
     Scheme httpsScheme = new Scheme("https", 443, sslSocketFactory); 
     httpClient.getConnectionManager().getSchemeRegistry().register(httpsScheme); 
    } 
    return httpClient; 
} 

とのSSLSocketFactoryクラス拡張:

を実際にあなたがサイファーを変更するために同じメカニズムを使用することができます、など

がHttpDestinationからのHttpClientを作成するには、この追加のコードを追加します。タイムアウト

import org.apache.http.conn.ssl.SSLSocketFactory; 
import org.apache.http.conn.ssl.X509HostnameVerifier; 
import org.apache.http.params.HttpParams; 

import javax.net.ssl.SSLContext; 
import javax.net.ssl.SSLSocket; 
import java.io.IOException; 
import java.net.InetAddress; 
import java.net.InetSocketAddress; 
import java.net.Socket; 

/** 
* Custom SSLSocketFactory to limit connections to specific TLS protocols. 
* 
* @author Juan Heyns 
*/ 
public class CustomSSLSocketFactory extends SSLSocketFactory { 

    private final String[] tlsProtocols; 

    public CustomSSLSocketFactory(SSLContext sslContext, X509HostnameVerifier hostnameVerifier, String[] tlsProtocols) { 
     super(sslContext, hostnameVerifier); 
     this.tlsProtocols = tlsProtocols; 
    } 

    @Override 
    public Socket connectSocket(Socket socket, InetSocketAddress remoteAddress, InetSocketAddress localAddress, HttpParams params) throws IOException { 
     return prepareSocket(super.connectSocket(socket, remoteAddress, localAddress, params)); 
    } 

    @Override 
    public Socket createLayeredSocket(Socket socket, String host, int port, boolean autoClose) throws IOException { 
     return prepareSocket(super.createLayeredSocket(socket, host, port, autoClose)); 
    } 

    @Override 
    public Socket createSocket(HttpParams params) throws IOException { 
     return prepareSocket(super.createSocket(params)); 
    } 

    @Override 
    @Deprecated 
    public Socket createSocket() throws IOException { 
     return prepareSocket(super.createSocket()); 
    } 

    @Override 
    @Deprecated 
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException { 
     return prepareSocket(super.createSocket(socket, host, port, autoClose)); 
    } 

    @Override 
    @Deprecated 
    public Socket connectSocket(Socket socket, String host, int port, InetAddress localAddress, int localPort, HttpParams params) throws IOException { 
     return prepareSocket(super.connectSocket(socket, host, port, localAddress, localPort, params)); 
    } 

    /** 
    * Any socket returned from this class will first be configured. 
    * 
    * @param socket 
    * @return 
    */ 
    private Socket prepareSocket(Socket socket) { 
     if (socket instanceof SSLSocket) { 
      SSLSocket sslSocket = (SSLSocket) socket; 
      sslSocket.setEnabledProtocols(tlsProtocols); 
     } 
     return socket; 
    } 

} 
関連する問題