Estou tentando executar o seguinte código no android
URLConnection l_connection = null;
// Create connection
uzip=new UnZipData(mContext);
l_url = new URL(serverurl);
if ("https".equals(l_url.getProtocol())) {
System.out.println("<<<<<<<<<<<<< Before TLS >>>>>>>>>>>>");
sslcontext = SSLContext.getInstance("TLS");
System.out.println("<<<<<<<<<<<<< After TLS >>>>>>>>>>>>");
sslcontext.init(null,
new TrustManager[] { new CustomTrustManager()},
new java.security.SecureRandom());
HttpsURLConnection
.setDefaultHostnameVerifier(new CustomHostnameVerifier());
HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext
.getSocketFactory());
l_connection = (HttpsURLConnection) l_url.openConnection();
((HttpsURLConnection) l_connection).setRequestMethod("POST");
} else {
l_connection = (HttpURLConnection) l_url.openConnection();
((HttpURLConnection) l_connection).setRequestMethod("POST");
}
/*System.setProperty("http.agent", "Android_Phone");*/
l_connection.setConnectTimeout(10000);
l_connection.setRequestProperty("Content-Language", "en-US");
l_connection.setUseCaches(false);
l_connection.setDoInput(true);
l_connection.setDoOutput(true);
System.out.println("<<<<<<<<<<<<< Before Connection >>>>>>>>>>>>");
l_connection.connect();
Ativado l_connection.connect()
, ele está fornecendo esta SSLhandshakeException. Às vezes funciona, mas na maioria das vezes dá a exceção. Isso só está acontecendo no emulador do Android 4.0. Eu testei no Android 4.4 e 5.0, funciona bem. Qual poderia ser a causa disso? Por favor ajude
STACKTRACE
04-28 15:51:13.143: W/System.err(2915): javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x870c918: Failure in SSL library, usually a protocol error
04-28 15:51:13.143: W/System.err(2915): error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:658 0xb7c393a1:0x00000000)
04-28 15:51:13.143: W/System.err(2915): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:460)
04-28 15:51:13.143: W/System.err(2915): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:257)
04-28 15:51:13.143: W/System.err(2915): at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:210)
04-28 15:51:13.143: W/System.err(2915): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:477)
04-28 15:51:13.153: W/System.err(2915): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:441)
04-28 15:51:13.153: W/System.err(2915): at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282)
04-28 15:51:13.153: W/System.err(2915): at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:232)
04-28 15:51:13.153: W/System.err(2915): at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:80)
04-28 15:51:13.153: W/System.err(2915): at libcore.net.http.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:164)
04-28 15:51:13.153: W/System.err(2915): at com.ofss.fcdb.mobile.android.rms.helpers.NetworkConnector.getConnection(NetworkConnector.java:170)
04-28 15:51:13.153: W/System.err(2915): at com.ofss.fcdb.mobile.android.rms.util.InitiateRMS$2.run(InitiateRMS.java:221)
04-28 15:51:13.153: W/System.err(2915): at java.lang.Thread.run(Thread.java:856)
04-28 15:51:13.153: W/System.err(2915): Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x870c918: Failure in SSL library, usually a protocol error
04-28 15:51:13.153: W/System.err(2915): error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:658 0xb7c393a1:0x00000000)
04-28 15:51:13.153: W/System.err(2915): at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(Native Method)
04-28 15:51:13.153: W/System.err(2915): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:410)
04-28 15:51:13.153: W/System.err(2915): ... 11 more
04-28 16:42:44.139: W/ResourceType(3140): No package identifier when getting value for resource number 0x00000000
android
ssl
sslhandshakeexception
android-4.0.3-ice-cream-sandwich
Bhavit S. Sengar
fonte
fonte
Respostas:
Eu encontrei a solução para isso analisando os pacotes de dados usando o WireShark. O que descobri é que, ao fazer uma conexão segura, o Android estava voltando para SSLv3 de TLSv1 . É um bug nas versões do Android <4.4 e pode ser resolvido removendo o protocolo SSLv3 da lista de protocolos ativados. Eu fiz uma classe socketFactory personalizada chamada NoSSLv3SocketFactory.java. Use isso para fazer uma fábrica de soquete.
Use esta classe assim ao conectar:
ATUALIZAÇÃO:
Agora, a solução correta seria instalar um novo provedor de segurança usando o Google Play Services :
Isso efetivamente dá ao seu aplicativo acesso a uma versão mais recente do OpenSSL e do Java Security Provider, que inclui suporte para TLSv1.2 em SSLEngine. Assim que o novo provedor for instalado, você pode criar um SSLEngine que suporte SSLv3, TLSv1, TLSv1.1 e TLSv1.2 da maneira usual:
Ou você pode restringir os protocolos habilitados usando
engine.setEnabledProtocols
.Não se esqueça de adicionar a seguinte dependência ( verifique a versão mais recente aqui ):
Para mais informações, confira este link .
fonte
Cenário
Eu estava recebendo exceções SSLHandshake em dispositivos que executam versões do Android anteriores ao Android 5.0. Em meu caso de uso, também queria criar um TrustManager para confiar em meu certificado de cliente.
Implementei NoSSLv3SocketFactory e NoSSLv3Factory para remover SSLv3 da lista de protocolos suportados do meu cliente, mas nenhuma dessas soluções funcionou.
Algumas coisas que aprendi:
O que funcionou para mim
Permitir a segurança do Android
Provider
atualizada ao iniciar seu aplicativo.O provedor padrão anterior a 5.0+ não desabilita SSLv3. Desde que você tenha acesso aos serviços do Google Play, é relativamente simples corrigir o provedor de segurança do Android a partir de seu aplicativo.
Se agora você criar seu OkHttpClient ou HttpURLConnection, TLSv1.1 e TLSv1.2 devem estar disponíveis como protocolos e SSLv3 deve ser removido. Se o cliente / conexão (ou mais especificamente é SSLContext) foi inicializado antes de chamar
ProviderInstaller.installIfNeeded(...)
, será necessário recriá-lo.Não se esqueça de adicionar a seguinte dependência ( versão mais recente encontrada aqui ):
Fontes:
a parte, de lado
Não precisei definir explicitamente quais algoritmos de criptografia meu cliente deve usar, mas encontrei uma postagem do SO recomendando aqueles considerados mais seguros no momento em que este artigo foi escrito: Quais suítes de criptografia habilitar para SSL Socket?
fonte
Além disso, você deve saber que pode forçar o TLS v1.2 para dispositivos Android 4.0 que não o tenham ativado por padrão:
Coloque este código em onCreate () do arquivo do seu aplicativo :
fonte
Anteriormente, também resolvi esse problema com a
SSLFactory
implementação customizada , mas de acordo com a documentação do OkHttp, a solução é muito mais fácil.Minha solução final com
TLS
cifras necessárias para dispositivos 4.2+ é assim:Observe que o conjunto de protocolos suportados depende da configuração em seu servidor.
fonte
Encontrei a solução aqui neste link .
Você apenas precisa colocar o código abaixo em sua classe de aplicativo Android. E isso é o suficiente. Não é necessário fazer nenhuma alteração nas configurações do Retrofit. Isso salvou meu dia.
Espero que isso seja útil. Obrigado.
fonte
Isso resolveu para mim:
android 4.1. habilitar tls1.1 e tls 1.2
fonte
Também tenho esse problema de relatório de erro. Meu código está abaixo.
Tenho meu Springboot como back-end e uso o Android OKHttp para obter informações. O erro crítico que cometi foi usar um .url ( "https : //10.0.2.2: 8010 / getShopInfo / aaa") no código do Android. Mas o meu back-end não tem permissão para solicitação de https. Depois de usar .url (" http : //10.0.2.2: 8010 / getShopInfo / aaa") , meu código funcionou bem. Então, quero dizer que meu erro não é a versão do emulador, é sobre o protocolo de solicitação. Encontro outro problema depois de fazer o que eu disse, mas é outro problema, e anexei o método de resolução do novo problema .
Boa sorte! CARA!
fonte
Foi reproduzível apenas quando eu uso proxy no genymotion (<4,4).
Verifique suas configurações de proxy em Configurações-> Redes sem fio e outras-> WiFi -> (Pressione longamente WiredSSID) -> Modificar rede
Selecione mostrar opções avançadas: defina as configurações de proxy como NENHUM.
fonte
Quando recebi esse erro, era porque os protocolos (versões TLS) e / ou conjuntos de criptografia suportados pelo servidor não estavam habilitados (e possivelmente nem mesmo suportados pelo) dispositivo. Para API 16-19, TLSv1.1 e TLSv1.2 são suportados, mas não habilitados por padrão. Depois de habilitá-los para essas versões, ainda recebo o erro porque essas versões não oferecem suporte a nenhuma das cifras em nossa instância do AWS CloudFront.
Como não é possível adicionar cifras ao Android, tivemos que mudar nossa versão do CloudFront de TLSv1.2_2018 para TLSv1.1_2016 (que ainda oferece suporte a TLSv1.2; apenas não exige), que tem quatro das cifras suportadas por as versões anteriores do Android, duas das quais ainda são consideradas fortes.
Nesse ponto, o erro desapareceu e as chamadas foram concluídas (com TLSv1.2) porque havia pelo menos um protocolo e pelo menos uma cifra que o dispositivo e o servidor compartilhavam.
Consulte as tabelas nesta página para ver quais protocolos e cifras são compatíveis e ativados em quais versões do Android.
Agora o Android estava realmente tentando usar SSLv3, conforme implícito na parte "falha de handshake de alerta sslv3" da mensagem de erro? Eu duvido; Suspeito que seja uma velha teia de aranha na biblioteca SSL que não foi limpa, mas não posso dizer com certeza.
Para habilitar TLSv1.2 (e TLSv1.1), consegui usar um muito mais simples do
SSLSocketFactory
que os vistos em outros lugares (comoNoSSLv3SocketFactory
). Ele simplesmente garante que os protocolos habilitados incluam todos os protocolos suportados e que as cifras habilitadas incluam todas as cifras suportadas (a última não era necessária para mim, mas poderia ser para outros) - vejaconfigure()
no final. Se você preferir ativar apenas os protocolos mais recentes, pode substituirsocket.supportedProtocols
por algo comoarrayOf("TLSv1.1", "TLSv1.2")
(da mesma forma para as cifras):fonte
Resolvi o problema com este: NoSSLv3SocketFactory.java
Classe principal:
fonte
Minha resposta está próxima das respostas acima, mas você precisa escrever a classe exatamente sem alterar nada.
}
e usá-lo com HttpsURLConnection
fonte