Para fines de prueba, estoy tratando de agregar una fábrica de sockets a mi cliente okHttp que confía en todo mientras se establece un proxy. Esto se ha hecho muchas veces, pero mi implementación de una fábrica de sockets de confianza parece faltar algo:
class TrustEveryoneManager implements X509TrustManager {
    @Override
    public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { }
    @Override
    public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { }
    @Override
    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
        return null;
    }
}
OkHttpClient client = new OkHttpClient();
final InetAddress ipAddress = InetAddress.getByName("XX.XXX.XXX.XXX"); // some IP
client.setProxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(ipAddress, 8888)));
SSLContext sslContext = SSLContext.getInstance("TLS");
TrustManager[] trustManagers = new TrustManager[]{new TrustEveryoneManager()};
sslContext.init(null, trustManagers, null);
client.setSslSocketFactory(sslContext.getSocketFactory);
No se envían solicitudes desde mi aplicación y no se registran excepciones, por lo que parece que está fallando silenciosamente dentro de okHttp. Tras una mayor investigación, parece que hay una excepción que se está tragando en okHttp Connection.upgradeToTls()cuando se fuerza el apretón de manos. La excepción que me están dando es:javax.net.ssl.SSLException: SSL handshake terminated: ssl=0x74b522b0: SSL_ERROR_ZERO_RETURN occurred. You should never see this.
El siguiente código produce un SSLContextque funciona como un encanto para crear un SSLSocketFactory que no arroja ninguna excepción:
protected SSLContext getTrustingSslContext() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
    final SSLContextBuilder trustingSSLContextBuilder = SSLContexts.custom()
            .loadTrustMaterial(null, new TrustStrategy() {
                @Override
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    return true; // Accepts any ssl cert whether valid or not.
                }
            });
    return trustingSSLContextBuilder.build();
}
El problema es que estoy tratando de eliminar todas las dependencias de Apache HttpClient de mi aplicación por completo. El código subyacente con Apache HttpClient para producir el SSLContextparece bastante sencillo, pero obviamente me falta algo ya que no puedo configurar mi SSLContextpara que coincida con esto.
¿Alguien podría producir una implementación SSLContext que haga lo que me gustaría sin usar Apache HttpClient?
fuente

java.net.SocketTimeoutException: Read timed outRespuestas:
En caso de que alguien caiga aquí, la (única) solución que funcionó para mí es crear lo
OkHttpClientque se explica aquí .Aquí está el código:
fuente
SSLy noTLS?X509TrustManager.getAcceptedIssuers()debe devolver una matriz vacía en lugar denull. Para obtener más información, consulte esta confirmación (desplácese hacia abajo y vea las notas en RealTrustRootIndex.java).Handshake failedexcepción. ¿Alguna sugerencia?El siguiente método está obsoleto
Considere actualizarlo a
fuente
Actualice OkHttp 3.0, la
getAcceptedIssuers()función debe devolver una matriz vacía en lugar denull.fuente
Fuente: documentación OkHttp
fuente
sslContextviene el?sslContext?Esta es la solución de sonxurxo en Kotlin, si alguien la necesita.
fuente
Hice una función de extensión para Kotlin. Péguelo donde quiera e impórtelo mientras crea
OkHttpClient.úsalo así:
fuente
Esta es la solución de Scala si alguien la necesita
}
fuente
¡Nunca debe buscar anular la validación del certificado en el código! Si necesita realizar una prueba, utilice una CA interna / de prueba e instale el certificado raíz de la CA en el dispositivo o emulador. Puede usar BurpSuite o Charles Proxy si no sabe cómo configurar una CA.
fuente