Para fins de teste, estou tentando adicionar uma fábrica de soquetes ao meu cliente okHttp que confie em tudo enquanto um proxy é definido. Isso foi feito muitas vezes, mas minha implementação de uma fábrica de soquetes confiáveis parece estar faltando alguma coisa:
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);
Nenhuma solicitação está sendo enviada para fora do meu aplicativo e nenhuma exceção está sendo registrada, então parece que ele está falhando silenciosamente em okHttp. Após uma investigação mais aprofundada, parece que há uma exceção sendo engolida em okHttp Connection.upgradeToTls()
quando o aperto de mão está sendo forçado. A exceção que estou recebendo é:javax.net.ssl.SSLException: SSL handshake terminated: ssl=0x74b522b0: SSL_ERROR_ZERO_RETURN occurred. You should never see this.
O código a seguir produz um SSLContext
que funciona perfeitamente na criação de um SSLSocketFactory que não lança nenhuma exceção:
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();
}
O problema é que estou tentando remover todas as dependências do Apache HttpClient do meu aplicativo completamente. O código subjacente com Apache HttpClient para produzir o SSLContext
parece bastante direto, mas obviamente estou faltando algo porque não posso configurar meu SSLContext
para corresponder a isso.
Alguém seria capaz de produzir uma implementação SSLContext que faz o que eu gostaria sem usar o Apache HttpClient?
fonte
java.net.SocketTimeoutException: Read timed out
Respostas:
Caso alguém caia aqui, a (única) solução que funcionou para mim é criar o
OkHttpClient
semelhante explicado aqui .Aqui está o código:
fonte
SSL
e nãoTLS
?X509TrustManager.getAcceptedIssuers()
deve retornar um array vazio em vez denull
. Para obter mais informações, consulte este commit (role para baixo e veja as notas em RealTrustRootIndex.java).Handshake failed
exceção. Alguma sugestão?O método a seguir está obsoleto
Considere atualizá-lo para
fonte
Atualize o OkHttp 3.0, a
getAcceptedIssuers()
função deve retornar uma matriz vazia em vez denull
.fonte
Fonte: documentação OkHttp
fonte
sslContext
vem isso?sslContext
?Esta é a solução da sonxurxo em Kotlin, se alguém precisar.
fonte
Fiz uma função de extensão para Kotlin. Cole-o onde quiser e importe-o enquanto cria
OkHttpClient
.use-o assim:
fonte
Esta é a solução Scala se alguém precisar
}
fonte
Você nunca deve procurar substituir a validação do certificado no código! Se você precisar fazer testes, use uma CA interna / de teste e instale o certificado raiz da CA no dispositivo ou emulador. Você pode usar BurpSuite ou Charles Proxy se não souber como configurar uma CA.
fonte