Estou tentando fazer conexões HTTPS usando HttpClient
lib, mas o problema é que, como o certificado não é assinado por uma Autoridade de Certificação (CA) reconhecida como Verisign , GlobalSIgn , etc., listado no conjunto de Certificados confiáveis do Android, Eu continuo recebendo javax.net.ssl.SSLException: Not trusted server certificate
.
Vi soluções em que você simplesmente aceita todos os certificados, mas e se eu quiser perguntar ao usuário?
Quero obter uma caixa de diálogo semelhante à do navegador, permitindo que o usuário decida continuar ou não. De preferência, eu gostaria de usar o mesmo armazenamento de certificados que o navegador. Alguma ideia?
Respostas:
A primeira coisa que você precisa fazer é definir o nível de verificação. Tais níveis não são tanto:
Embora o método setHostnameVerifier () seja obsoleto para a nova biblioteca apache, a versão no Android SDK é normal. E assim nós pegamos
ALLOW_ALL_HOSTNAME_VERIFIER
e colocamos na fábrica de métodosSSLSocketFactory.setHostnameVerifier()
.Em seguida, você precisa definir nossa fábrica para o protocolo como https. Para fazer isso, basta chamar o
SchemeRegistry.register()
métodoEntão você precisa criar um
DefaultHttpClient
comSingleClientConnManager
. Também no código abaixo, você pode ver que, por padrão, também usará nossa flag (ALLOW_ALL_HOSTNAME_VERIFIER
) pelo métodoHttpsURLConnection.setDefaultHostnameVerifier()
O código abaixo funciona para mim:
fonte
org.apache.http.conn.ssl.SSLSocketFactory
por que eu quero usarjavax.net.ssl.HttpsURLConnection
??As etapas principais a seguir são necessárias para obter uma conexão segura das autoridades de certificação que não são consideradas confiáveis pela plataforma Android.
Conforme solicitado por muitos usuários, espelhei as partes mais importantes do artigo do meu blog aqui:
java.net.ssl.HttpsURLConnection
(mais fácil de entender, mais eficiente)Pegue os certs
É necessário obter todos os certificados que constroem uma cadeia a partir do certificado do terminal até a CA raiz. Isso significa que qualquer certificado CA intermediário (se presente) e também o certificado CA raiz. Você não precisa obter o certificado do terminal.
Crie o keystore
Faça o download do provedor BouncyCastle e armazene-o em um local conhecido. Verifique também se você pode chamar o comando keytool (geralmente localizado na pasta bin da instalação do JRE).
Agora importe os certificados obtidos (não importe o certificado do terminal) para um keystore no formato BouncyCastle.
Não testei, mas acho importante a ordem de importação dos certificados. Isso significa, importe primeiro o certificado CA intermediário mais baixo e depois o certificado CA raiz.
Com o comando a seguir, um novo keystore (se ainda não estiver presente) com a senha mysecret será criado e o certificado CA intermediário será importado. Também defini o provedor BouncyCastle, onde ele pode ser encontrado no meu sistema de arquivos e no formato keystore. Execute este comando para cada certificado na cadeia.
Verifique se os certificados foram importados corretamente no keystore:
Deve gerar toda a cadeia:
Agora você pode copiar o keystore como um recurso bruto no seu aplicativo Android em
res/raw/
Use o keystore no seu aplicativo
Primeiro, precisamos criar um Apache HttpClient personalizado que use nosso keystore para conexões HTTPS:
Criamos nosso HttpClient personalizado, agora podemos usá-lo para conexões seguras. Por exemplo, quando fazemos uma chamada GET para um recurso REST:
É isso aí ;)
fonte
/res/raw/mykeystore.bks
, embora não seja possível resolver a referência a ele. como resolver isso?Se você possui um certificado personalizado / autoassinado no servidor que não existe no dispositivo, pode usar a classe abaixo para carregá-lo e usá-lo no lado do cliente no Android:
Coloque o
*.crt
arquivo de certificado em/res/raw
para que esteja disponível emR.raw.*
Use a classe abaixo para obter um
HTTPClient
ouHttpsURLConnection
que terá uma fábrica de soquetes usando esse certificado:Pontos chave:
Certificate
objetos são gerados a partir de.crt
arquivos.KeyStore
é criado.keyStore.setCertificateEntry("ca", cert)
está adicionando certificado ao armazenamento de chaves com o alias "ca". Você modifica o código para adicionar mais certificados (CA intermediária, etc.).SSLSocketFactory
que possa ser usado porHTTPClient
ouHttpsURLConnection
.SSLSocketFactory
pode ser configurado ainda mais, por exemplo, para ignorar a verificação do nome do host etc.Mais informações em: http://developer.android.com/training/articles/security-ssl.html
fonte
.crt
arquivos? Baixar de um servidor?Fiquei frustrado ao tentar conectar meu aplicativo Android ao meu serviço RESTful usando https. Também fiquei um pouco irritado com todas as respostas que sugeriram desativar completamente a verificação de certificado. Se você fizer isso, qual é o sentido de https?
Depois de pesquisar um pouco sobre o assunto por um tempo, finalmente encontrei esta solução em que frascos externos não são necessários, apenas APIs do Android. Agradecimentos a Andrew Smith, que publicou em julho de 2014
Funcionou bem para o meu aplicativo de maquete.
fonte
import java.security.cert.X509Certificate;
A resposta principal não funcionou para mim. Após alguma investigação, encontrei as informações necessárias em "Desenvolvedor Android": https://developer.android.com/training/articles/security-ssl.html#SelfSigned
A criação de uma implementação vazia do X509TrustManager fez o truque:
Esteja ciente de que esta implementação vazia do TustManager é apenas um exemplo e usá-lo em um ambiente produtivo causaria uma grave ameaça à segurança!
fonte
O Google recomenda o uso do Android Volley para conexões HTTP / HTTPS , pois isso
HttpClient
foi preterido. Então, você sabe a escolha certa :).E também NUNCA NUKE Certificados SSL (NUNCA !!!).
Nuke Certificados SSL é totalmente contra o objetivo do SSL, que está promovendo a segurança . Não há sentido em usar SSL, se você planeja bombardear todos os certificados SSL que vêm. Uma solução melhor seria, sem usar SSL, ou uma solução melhor, seria criar um personalizado
TrustManager
no seu App + usando o Android Volley para conexões HTTP / HTTPS.Aqui está uma Gist que eu criei, com um LoginApp básica, realizando conexões HTTPS, usando um certificado auto-assinado no lado do servidor, aceito na App.
Aqui também está outra lista essencial que pode ajudar, para criar certificados SSL autoassinados para configurar no seu servidor e também usar o certificado no seu aplicativo. Muito importante: você deve copiar o arquivo .crt gerado pelo script acima, para o diretório "bruto" do seu projeto Android.
fonte
Veja como você pode adicionar certificados adicionais ao KeyStore para evitar esse problema: Confiando em todos os certificados usando HttpClient sobre HTTPS
Ele não solicitará o usuário como você solicitou, mas tornará menos provável que o usuário encontre um erro "Certificado de servidor não confiável".
fonte
Maneira mais simples de criar certificado SSL
Abra o Firefox (suponho que também seja possível com o Chrome, mas é mais fácil para mim com o FF)
Visite seu site de desenvolvimento com um certificado SSL autoassinado.
Clique no certificado (ao lado do nome do site)
Clique em "Mais informações"
Clique em "Ver certificado"
Clique em "Detalhes"
Clique em "Exportar ..."
Escolha "Certificado X.509 com cadeia (PEM)", selecione a pasta e o nome para salvá-lo e clique em "Salvar"
Vá para a linha de comando, para o diretório em que você baixou o arquivo pem e execute "openssl x509 -inform PEM -outform DM -in .pem -out .crt"
Copie o arquivo .crt para a raiz da pasta / sdcard dentro do seu dispositivo Android Dentro do seu dispositivo Android, Configurações> Segurança> Instalar do armazenamento.
Ele deve detectar o certificado e permitir que você o adicione ao dispositivo Navegue até o site de desenvolvimento.
Na primeira vez, você deverá confirmar a exceção de segurança. Isso é tudo.
O certificado deve funcionar com qualquer navegador instalado no seu Android (navegador, Chrome, Opera, Dolphin ...)
Lembre-se de que, se você estiver exibindo seus arquivos estáticos de um domínio diferente (todos nós somos cadelas de velocidade da página), também precisará adicionar o certificado para esse domínio.
fonte
Eu escrevi uma pequena biblioteca ssl-utils-android para confiar em um certificado específico no Android.
Você pode simplesmente carregar qualquer certificado, fornecendo o nome do arquivo no diretório de ativos.
Uso:
fonte
Nenhuma dessas correções funcionou para minha plataforma de desenvolvimento direcionada ao SDK 16, versão 4.1.2, por isso encontrei uma solução alternativa.
Meu aplicativo armazena dados no servidor usando " http://www.example.com/page.php?data=somedata "
Recentemente, o page.php foi movido para " https://www.secure-example.com/page.php " e continuo recebendo "javax.net.ssl.SSLException: certificado de servidor não confiável".
Em vez de aceitar todos os certificados para apenas uma única página, começando com este guia , resolvi meu problema escrevendo meu próprio page.php publicado em " http://www.example.com/page.php "
fonte
19 de janeiro de 2020 - Certificado autoassinado FIXO DE EMISSÃO:
Para reproduzir vídeo, imagem, chamar o serviço da web para obter qualquer certificado autoassinado ou conectar-se a qualquer URL não seguro, basta chamar esse método antes de executar qualquer ação, o problema será resolvido com relação ao certificado:
CÓDIGO KOTLIN
fonte
Talvez isso seja útil ... funciona em clientes java usando certificados autoassinados (não há verificação do certificado). Tenha cuidado e use-o apenas para casos de desenvolvimento, porque isso não é seguro!
Como ignorar erros de certificado SSL no Apache HttpClient 4.0
Espero que funcione no Android apenas adicionando a biblioteca HttpClient ... boa sorte !!
fonte
Esse é um problema resultante da falta de suporte ao SNI (Server Name Identification) em A, ndroid 2.x. Eu estava lutando com esse problema por uma semana até me deparar com a seguinte pergunta, que não apenas fornece uma boa base do problema, mas também fornece uma solução funcional e eficaz sem quaisquer falhas de segurança.
Erro 'No peer certificate' no Android 2.3, mas NÃO no 4
fonte