Erro SSL “Peer Not Authenticated” com HttpClient 4.1

Eu estou construindo um monitor de aplicativo simples para pesquisar um dos nossos URLs de API e nos enviar um email se ele não puder obter um código de status HTTP 200 da resposta (isso indicaria que nossa API está inativa por algum motivo).

Estou usando o HttpClient 4.1 (isso é importante porque sua API é muito diferente da 3.x).

Nossa API é segura com SSL, no entanto, inserindo:

http://example.com/our-api

em um navegador da web redireciona você para

https://example.com/our-api

Sem causar erros.

Quando o HttpClient tenta acessar essa URL ( http://example.com/our-api ), ele falha com uma exceção javax.net.ssl.SSLPeerUnverifiedException com uma mensagem informando:

peer não autenticado

Eu vejo isso acontecendo muito para outras pessoas como é evidenciado por este post (que também fornece algumas maneiras de contornar esse problema – uma solução que eu vou tentar implementar hoje à noite, de fato).

O que este outro post (e os outros semelhantes a ele) não faz é explicar por que isso está acontecendo em primeiro lugar! Então, ao invés de perguntar “como eu corrijo isso?” Pensei em perguntar ” por que isso está acontecendo? ” Antes de prosseguir com uma das soluções propostas, gostaria de saber qual é o problema que estou tentando consertar 😉

Se o certificado do servidor for autoassinado, isso funcionará conforme projetado e você terá que importar o certificado do servidor para seu keystore.

Supondo que o certificado do servidor seja assinado por uma autoridade de certificação bem conhecida, isso ocorre porque o conjunto de certificados de autoridade de certificação disponível para um navegador moderno é muito maior do que o conjunto limitado fornecido com o JDK / JRE.

A solução EasySSL fornecida em uma das postagens mencionadas apenas oculta o erro e você não saberá se o servidor possui um certificado válido.

Você deve importar a CA raiz adequada para o seu keystore para validar o certificado. Há uma razão pela qual você não pode contornar isso com o código SSL do estoque, e isso é para evitar que você escreva programas que se comportam como se fossem seguros, mas não são.

Isso é lançado quando

… o par não foi capaz de se identificar (por exemplo, nenhum certificado, o pacote de criptografia específico sendo usado não suporta autenticação ou nenhuma autenticação de peer foi estabelecida durante o handshaking SSL) essa exceção é lançada.

Provavelmente, a causa dessa exceção (onde está o stacktrace) mostrará por que essa exceção é lançada. O mais provável é que o keystore padrão enviado com Java não contenha (e confie) o certificado raiz do TTP que está sendo usado.

A resposta é recuperar o certificado raiz (por exemplo, da conexão SSL de seus navegadores), importá-lo para o arquivo cacerts e confiar nele usando keytool que é fornecido pelo Java JDK. Caso contrário, você terá que atribuir outro armazenamento confiável programaticamente.

Eu não sou um desenvolvedor java, mas estava usando um aplicativo java para testar uma API RESTful. Para que eu conserte o erro tive que instalar os certificados intermediários no servidor web para fazer com que o erro desaparecesse. Eu estava usando lighttpd, o certificado original foi instalado em um servidor IIS. Espero que ajude. Esses eram os certificados que eu tinha perdido no servidor.

  • CA.crt
  • UTNAddTrustServer_CA.crt
  • AddTrustExternalCARoot.crt
 keytool -import -v -alias cacerts -keystore cacerts.jks -storepass changeit -file C:\cacerts.cer 
Intereting Posts