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 SSLContext
que 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 SSLContext
parece bastante sencillo, pero obviamente me falta algo ya que no puedo configurar mi SSLContext
para 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 out
Respuestas:
En caso de que alguien caiga aquí, la (única) solución que funcionó para mí es crear lo
OkHttpClient
que se explica aquí .Aquí está el código:
fuente
SSL
y 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 failed
excepció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
sslContext
viene 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