Deseo fuerza Apache Commons HTTP-Cliente (versión 3.1) para el uso de TLS 1.2 como el sólo protocolo HTTPS.

Esto es debido a que el servidor supuestamente actualizado al TLS 1.2 y no aceptar cualquier protocolo más antiguo ya (causante de la Conexión ‘Reset’ para ser devueltos).

Para más contexto, probablemente irrelevante, el HTTP de Cliente se utiliza junto con Axis2 para hacer un JABÓN; de la parte del código que se utiliza para configurar el HttpClient es el siguiente:

MultiThreadedHttpConnectionManager connMgr = new MultiThreadedHttpConnectionManager();
this.httpClient = new HttpClient(connMgr);

//initialize HttpClient parameters
HttpClientParams hcParams = this.httpClient.getParams();

//Maximum time to wait to receive connection from pool
hcParams.setConnectionManagerTimeout(this.maxWait);
hcParams.setSoTimeout(this.timeout);
hcParams.setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(this.retryCount, false));

//Initialize global Connection manager parameters
HttpConnectionManagerParams cmParams = connMgr.getParams();
cmParams.setDefaultMaxConnectionsPerHost(this.maxActive);
cmParams.setStaleCheckingEnabled(this.checkStaleConnections);
cmParams.setConnectionTimeout(this.timeout);

Muchas gracias por la ayuda!

  • Puesto que usted está utilizando este viejo y sin mantenimiento de software asumo que usted está usando una vieja versión de Java también. Está seguro de que su Java es capaz de hablar de Java 1.2 (es decir, que la versión de Java que se utilizan?)
  • No estoy usando Java 7, y el código no es demasiado antiguo, funciona bastante bien hasta ahora.

3 Comentarios

  1. 26

    Lástima que nadie respondió; yo era capaz de hacerlo, primero se escribe un CustomHttpSocketFactory, entonces:

    String scheme = "https";
    Protocol baseHttps = Protocol.getProtocol(scheme);
    int defaultPort = baseHttps.getDefaultPort();
    
    ProtocolSocketFactory baseFactory = baseHttps.getSocketFactory();
    ProtocolSocketFactory customFactory = new CustomHttpsSocketFactory(baseFactory);
    
    Protocol customHttps = new Protocol(scheme, customFactory, defaultPort);
    Protocol.registerProtocol(scheme, customHttps); 

    Una muestra personalizada zócalo de fábrica el código se encuentra aquí, sino que me hizo:

    public class CustomHttpsSocketFactory implements SecureProtocolSocketFactory
    {
    
       private final SecureProtocolSocketFactory base;
    
       public CustomHttpsSocketFactory(ProtocolSocketFactory base)
       {
          if(base == null || !(base instanceof SecureProtocolSocketFactory)) throw new IllegalArgumentException();
          this.base = (SecureProtocolSocketFactory) base;
       }
    
       private Socket acceptOnlyTLS12(Socket socket)
       {
          if(!(socket instanceof SSLSocket)) return socket;
          SSLSocket sslSocket = (SSLSocket) socket;
          sslSocket.setEnabledProtocols(new String[]{"TLSv1.2" });
          return sslSocket;
       }
    
       @Override
       public Socket createSocket(String host, int port) throws IOException
       {
          return acceptOnlyTLS12(base.createSocket(host, port));
       }
       @Override
       public Socket createSocket(String host, int port, InetAddress localAddress, int localPort) throws IOException
       {
          return acceptOnlyTLS12(base.createSocket(host, port, localAddress, localPort));
       }
       @Override
       public Socket createSocket(String host, int port, InetAddress localAddress, int localPort, HttpConnectionParams params) throws IOException
       {
          return acceptOnlyTLS12(base.createSocket(host, port, localAddress, localPort, params));
       }
       @Override
       public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException
       {
          return acceptOnlyTLS12(base.createSocket(socket, host, port, autoClose));
       }
    
    }
    • Es SecureProtocolSocketFactory diferente de SSLSocketFactory?
    • SecureProtocolSocketFactory es una interfaz en Apache HTTPClient útil para la aplicación de una costumbre zócalo de fábrica; I creo java SSLSocketFactory sería menos útil en este caso.
    • Tengo el mismo requisito, excepto que estoy usando HTTP-Cliente (versión 4.1). Su código es útil a pesar de que todavía no estoy claro de dónde eres unión httpClient con este Protocolo registrado?
    • ¿por qué necesita separar la clase en este caso y cuál es el uso de RegisterProtocol ? ¿Cómo es que los métodos de CustomHttpsSocketFactory se llama?
    • Se trata de mostrar setEnabledProtocols(String[]); no está definido por el tipo de javax.net.ssl.SSLSocket.
  2. 2

    Usted necesita un Socket de referencia en el código. A continuación, puede establecer protocolos habilitados en esta forma:

    if (socket != null && (socket instanceof SSLSocket)) {
        ((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.2"});
    }
    • Estoy confundido en cuanto a cómo usar esto en mi aplicación de HttpClient (3.1). Dónde está el zócalo objeto inicializado? Quiero también que los protocolos I conjunto son utilizados solamente por mi HttpClient pero ninguna de las otras clases/implementaciones que puedan hacer peticiones http en otros lugares. El uso de Java 8, y no se puede actualizar a otras versiones de HttpClient en este momento.
    • Este es Java socket: docs.oracle.com/javase/7/docs/api/javax/net/ssl/SSLSocket.html
    • Eso no significa que el HttpClient, cuya guía dice «HttpClient proporciona soporte completo para HTTP sobre SSL (Secure Sockets Layer) o IETF Seguridad de Capa de Transporte (TLS) protocolos aprovechando el Java Secure Socket Extensión (JSSE). «, significa que, por defecto, las tomas de corriente proporcionado por Java 8, están habilitados? Por lo que el soporte hasta TLSv1.2? Mi intención es averiguar qué protocolo se utiliza de forma predeterminada y, a continuación, asegúrese de que al menos SSL 3.0 y adelante son compatibles. Resultó ser más difícil de encontrar fuera de lo esperado, tal vez estoy haciendo las preguntas equivocadas. Gracias!
  3. 2

    Depende de cómo usted está escribiendo sus clientes y qué versiones JRE está utilizando:

    Si usted está usando JRE8 (a menos que usted haya sustituido el valor predeterminado SunJSSE que viene con JRE8), no es una propiedad del sistema «jdk.tls.cliente.los protocolos». De forma predeterminada, lo que usted menciona aquí será utilizado para todas las comunicaciones del cliente.

    Si usted está usando HttpsURLConnection objeto de conexión de cliente, u puede utilizar el sistema de propiedad «https.los protocolos». Esto funciona para todas las versiones de JRE, no sólo JRE8.

    Si no se especifica nada, por TLS clientes, en JRE8, TLSv1, v1.1 y v1.2 están habilitadas, por lo que funciona con un servidor lo admite cualquiera de las versiones. Sin embargo, en JRE7 por defecto TLSv1 solo está habilitado.

    En el código de la u siempre se puede reemplazar el valor predeterminado o lo que u pasar a través de las propiedades del sistema. Lo que u establecidas en el código tendrá mayor prioridad. Para reemplazar en el código…

    1) Si usted está usando raw socket y SSLEngine, u puede establecer el protocolo y sistemas de cifrado en el SSLEngine (sslEngine.setEnabledProtocols(..)

    2) Si usted está utilizando SSLSocket, u puede establecer el protocolo y sistemas de cifrado en el SSLSocket (sslSocket.setEnabledProtocols(..)

    Usted puede también conseguir un SSLContext con el protocolo necesario habilitado y el uso que de lo SSL componentes. SSLContext.getInstance(«TLSvx.x»). Tenga en cuenta que por defecto va a devolver un contexto con todos los protocolos menor que TLSvx.x activado. Si tienes configurado «jdk.tls.cliente.los protocolos», éste devolverá un contexto con los protocolos habilitados.

    No sería una buena idea codificado los protocolos en el código. Muy a menudo, nos vamos a encontrar con algunos clientes quieren versión específica, ya sea porque utilizan servidores antiguos o algunos graves vulnerabilidades se encuentran en algunas versiones de TLS. Establecer a través de las propiedades del sistema o incluso si usted es establecer explícitamente en sslsocket o sslengine, leer que desde algunas conf archivo.

    Consulte también:

    https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html

    http://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html

Dejar respuesta

Please enter your comment!
Please enter your name here