Parece uma pergunta padrão, mas não consegui encontrar direções claras em nenhum lugar.
Eu tenho o código java tentando conectar a um servidor com certificado provavelmente autoassinado (ou expirado). O código relata o seguinte erro:
[HttpMethodDirector] I/O exception (javax.net.ssl.SSLHandshakeException) caught
when processing request: sun.security.validator.ValidatorException: PKIX path
building failed: sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target
Pelo que entendi, eu tenho que usar o keytool e dizer ao java que não há problema em permitir essa conexão.
Todas as instruções para corrigir esse problema pressupõem que eu seja totalmente competente com o keytool, como
gerar chave privada para o servidor e importá-la para o keystore
Existe alguém que possa postar instruções detalhadas?
Estou executando o unix, então o script bash seria melhor.
Não tenho certeza se é importante, mas o código é executado no jboss.
Respostas:
Você tem basicamente duas opções aqui: adicione o certificado autoassinado ao seu armazenamento confiável da JVM ou configure seu cliente para
Opção 1
Exporte o certificado do seu navegador e importe-o no seu armazenamento confiável da JVM (para estabelecer uma cadeia de confiança):
opção 2
Desativar validação de certificado:
Observe que eu não recomendo a opção 2 . Desativar o gerenciador de confiança derrota algumas partes do SSL e torna você vulnerável aos ataques intermediários. Prefira a opção 1 ou, melhor ainda, faça com que o servidor use um certificado "real" assinado por uma CA conhecida.
fonte
Persegui esse problema em um provedor de certificados que não faz parte dos hosts confiáveis da JVM padrão a partir de
JDK 8u74
. O provedor é www.identrust.com , mas esse não era o domínio ao qual eu estava tentando me conectar. Esse domínio recebeu seu certificado desse provedor. Consulte A raiz cruzada cobrirá a confiança na lista padrão no JDK / JRE? - leia algumas entradas. Consulte também Quais navegadores e sistemas operacionais suportam Let's Encrypt .Portanto, para me conectar ao domínio em que me interessava, que tinha um certificado emitido
identrust.com
, executei as etapas a seguir. Basicamente, eu tive que obter o identrust.com (DST Root CA X3
certificado ) para ser confiável pela JVM. Consegui fazer isso usando o Apache HttpComponents 4.5 da seguinte forma:1: Obtenha o certificado da indettrust em Instruções para download da cadeia de certificados . Clique no link DST Root CA X3 .
2: Salve a seqüência de caracteres em um arquivo chamado "DST Root CA X3.pem". Certifique-se de adicionar as linhas "----- COMEÇAR CERTIFICADO -----" e "----- TERMINAR CERTIFICADO -----" no arquivo no início e no final.
3: Crie um arquivo java keystore, cacerts.jks com o seguinte comando:
4: Copie o keystore cacerts.jks resultante no diretório de recursos do seu aplicativo java / (maven).
5: Use o código a seguir para carregar esse arquivo e anexá-lo ao Apache 4.5 HttpClient. Isso resolverá o problema para todos os domínios que possuem certificados emitidos a partir do
indetrust.com
util oracle, incluindo o certificado no keystore padrão do JRE.Quando o projeto é desenvolvido, o cacerts.jks será copiado no caminho de classe e carregado a partir daí. Neste momento, não testei em outros sites SSL, mas se o código acima "encadear" neste certificado, eles também funcionarão, mas, novamente, não sei.
Referência: contexto SSL personalizado e Como aceito um certificado autoassinado com um Java HttpsURLConnection?
fonte
O Apache HttpClient 4.5 suporta a aceitação de certificados autoassinados:
Isso cria uma fábrica de soquetes SSL que usará o
TrustSelfSignedStrategy
, registrará com um gerenciador de conexões personalizado e, em seguida, executará um HTTP GET usando esse gerenciador de conexões.Eu concordo com aqueles que cantam "não fazem isso na produção", no entanto, existem casos de uso para aceitar certificados autoassinados fora da produção; nós os usamos em testes de integração automatizados, para que possamos usar SSL (como na produção) mesmo quando não estiver em execução no hardware de produção.
fonte
Em vez de configurar o socket factory padrão (que IMO é uma coisa ruim) - você afetará apenas a conexão atual, e não todas as conexões SSL que você tentar abrir:
fonte
checkServerTrusted
não implementa a lógica necessária para realmente confiar no certificado e garantir que certificados não confiáveis sejam rejeitados. Isso pode fazer uma boa leitura: O código mais perigoso do mundo: validar certificados SSL em software que não seja o navegador .getAcceptedIssuers()
método não está em conformidade com a especificação e essa 'solução' permanece radicalmente insegura.Existe uma alternativa melhor para confiar em todos os certificados: crie um
TrustStore
que confie especificamente em um determinado certificado e use-o para criar um aSSLContext
partir do qual obter oSSLSocketFactory
conjuntoHttpsURLConnection
. Aqui está o código completo:Como alternativa, você pode carregar
KeyStore
diretamente o arquivo ou recuperar o certificado X.509 de qualquer fonte confiável.Observe que, com esse código, os certificados
cacerts
não serão usados. Este particularHttpsURLConnection
confiará apenas neste certificado específico.fonte
Confie em todos os certificados SSL: - Você pode ignorar o SSL se quiser testar no servidor de teste. Mas não use esse código para produção.
}
Por favor, chame essa função na função onCreate () em Activity ou em sua classe Application.
Isso pode ser usado para o Volley no Android.
fonte
A resposta aceita é boa, mas eu gostaria de adicionar algo a isso, pois estava usando o IntelliJ no Mac e não consegui fazê-lo funcionar usando a
JAVA_HOME
variável path.Acontece que o Java Home era diferente ao executar o aplicativo a partir do IntelliJ.
Para descobrir exatamente onde está, você pode fazer
System.getProperty("java.home")
o que é de onde os certificados confiáveis são lidos.fonte
Se 'eles' estiverem usando um certificado autoassinado, cabe a eles executar as etapas necessárias para tornar seu servidor utilizável. Especificamente, isso significa fornecer o certificado para você offline de maneira confiável. Então, faça com que eles façam isso. Em seguida, você importa isso para o seu armazenamento confiável usando o keytool, conforme descrito no Guia de Referência do JSSE. Nem pense no inseguro TrustManager postado aqui.
EDITAR Para o benefício dos dezessete (!) Votantes negativos e numerosos comentadores abaixo, que claramente não leram o que escrevi aqui, isso não é uma jeremia para certificados autoassinados. Não há nada de errado com certificados autoassinados quando implementados corretamente. Mas, a maneira correta de implementá-los é ter o certificado entregue com segurança por meio de um processo offline, em vez do canal não autenticado que eles serão usados para autenticar. Certamente isso é óbvio? É certamente óbvio para todas as organizações com consciência de segurança em que já trabalhei, desde bancos com milhares de agências até minhas próprias empresas. A 'solução' baseada em código do lado do cliente de confiança todoscertificados, incluindo certificados autoassinados assinados por absolutamente ninguém, ou por qualquer órgão arbitrário que se estabeleça como CA, ipso facto não é seguro. Está apenas brincando com segurança. É inútil. Você está tendo uma conversa particular, à prova de adulteração, à prova de resposta e à prova de injeção com ... alguém. Qualquer pessoa. Um homem no meio. Um imitador. Qualquer pessoa. Você também pode usar apenas texto simples.
fonte
Esta não é uma solução para o problema completo, mas a Oracle possui uma boa documentação detalhada sobre como usar este keytool. Isso explica como
https://docs.oracle.com/cd/E54932_01/doc.705/e54936/cssg_create_ssl_cert.htm#CSVSG178
fonte
Em vez de usar o keytool, conforme sugerido pelo comentário principal, no RHEL, você pode usar o update-ca-trust a partir das versões mais recentes do RHEL 6. Você precisará ter o certificado no formato pem. Então
Edite o /etc/pki/ca-trust/source/cert.p11-kit e altere "categoria do certificado: outra entrada" para "categoria do certificado: autoridade". (Ou use sed para fazer isso em um script.) Em seguida, faça
Algumas advertências:
update-ca-trust enable
. Isso substituirá o arquivo / etc / pki / java / cacerts por um link simbólico apontando para / etc / pki / ca-trust / extract / java / cacerts. (Portanto, convém fazer backup do primeiro.)fonte
Tive o problema de passar um URL para uma biblioteca que chamava de
url.openConnection();
adaptar a resposta de jon-daniel,Usando esta classe, é possível criar uma nova URL com:
Isso tem a vantagem de estar localizado e não substituir o padrão
URL.openConnection
.fonte