HttpGet com HTTPS: SSLPeerUnverifiedException

Usando o HttpClient , recebo o seguinte erro ao tentar se comunicar por HTTPS:

Exceção no thread “main” javax.net.ssl.SSLPeerUnverifiedException: ponto não autenticado.

Aqui está o meu código:

URI loginUri = new URI("https://myUrl.asp"); HttpClient httpclient = new DefaultHttpClient(); HttpGet httpget = new HttpGet( loginUri ); HttpResponse response = httpclient.execute( httpget ); 

Como suprimo ou removo esse erro?

Nota: Não faça isso no código de produção, use http em vez disso, ou a chave pública autoassinada como sugerido acima.

No HttpClient 4.xx:

 import static org.junit.Assert.assertEquals; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.cert.X509Certificate; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.impl.client.DefaultHttpClient; import org.junit.Test; public class HttpClientTrustingAllCertsTest { @Test public void shouldAcceptUnsafeCerts() throws Exception { DefaultHttpClient httpclient = httpClientTrustingAllSSLCerts(); HttpGet httpGet = new HttpGet("https://host_with_self_signed_cert"); HttpResponse response = httpclient.execute( httpGet ); assertEquals("HTTP/1.1 200 OK", response.getStatusLine().toString()); } private DefaultHttpClient httpClientTrustingAllSSLCerts() throws NoSuchAlgorithmException, KeyManagementException { DefaultHttpClient httpclient = new DefaultHttpClient(); SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, getTrustingManager(), new java.security.SecureRandom()); SSLSocketFactory socketFactory = new SSLSocketFactory(sc); Scheme sch = new Scheme("https", 443, socketFactory); httpclient.getConnectionManager().getSchemeRegistry().register(sch); return httpclient; } private TrustManager[] getTrustingManager() { TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { @Override public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } @Override public void checkClientTrusted(X509Certificate[] certs, String authType) { // Do nothing } @Override public void checkServerTrusted(X509Certificate[] certs, String authType) { // Do nothing } } }; return trustAllCerts; } } 

Esta resposta segue para as respostas de owlstead e Mat . Aplica-se a instalações SE / EE, não ao ME / mobile / Android SSL.

Como ninguém mencionou isso, mencionarei o “modo de produção” para corrigir isso: Siga as etapas da class AuthSSLProtocolSocketFactory em HttpClient para atualizar sua trust store e armazenamentos de chaves.

  1. Importar um certificado confiável e gerar um arquivo de armazenamento confiável

keytool -import -alias "my server cert" -file server.crt -keystore my.truststore

  1. Gere uma nova chave (use a mesma senha que o truststore)

keytool -genkey -v -alias "my client key" -validity 365 -keystore my.keystore

  1. Emitir uma solicitação de assinatura de certificado (CSR)

keytool -certreq -alias "my client key" -file mycertreq.csr -keystore my.keystore

  1. (auto-assinatura ou obter seu certificado assinado)

  2. Importar o certificado raiz da CA confiável

keytool -import -alias "my trusted ca" -file caroot.crt -keystore my.keystore

  1. Importe o arquivo PKCS # 7 contendo a cadeia completa de certificados

keytool -import -alias "my client key" -file mycert.p7 -keystore my.keystore

  1. Verificar o conteúdo do arquivo keystore resultante

keytool -list -v -keystore my.keystore

Se você não tiver um certificado de servidor, gere um no formato JKS e exporte-o como um arquivo CRT. Fonte: documentação do keytool

 keytool -genkey -alias server-alias -keyalg RSA -keypass changeit -storepass changeit -keystore my.keystore keytool -export -alias server-alias -storepass changeit -file server.crt -keystore my.keystore 

Usando o HttpClient 3.x, você precisa fazer isso:

 Protocol easyHttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443); Protocol.registerProtocol("https", easyHttps); 

Uma implementação do EasySSLProtocolSocketFactory pode ser encontrada aqui .

Essa exceção ocorrerá caso seu servidor seja baseado no JDK 7 e seu cliente esteja no JDK 6 e usando certificados SSL. No JDK 7, o handshaking de mensagem sslv2hello é desativado por padrão, enquanto no JDK 6 o handshaking de mensagem sslv2hello é ativado. Por esta razão, quando o seu cliente tentar se conectar ao servidor, uma mensagem sslv2hello será enviada para o servidor e, devido à desabilitação da mensagem sslv2hello, você receberá essa exceção. Para resolver isso, você precisa mover seu cliente para o JDK 7 ou usar a versão 6u91 do JDK. Mas para obter essa versão do JDK você tem que pegar o

Método retornando um “secureClient” (em um ambiente Java 7 – NetBeans IDE e GlassFish Server: port https por padrão 3920), espero que isso possa ajudar:

 public DefaultHttpClient secureClient() { DefaultHttpClient httpclient = new DefaultHttpClient(); SSLSocketFactory sf; KeyStore trustStore; FileInputStream trustStream = null; File truststoreFile; // java.security.cert.PKIXParameters for the trustStore PKIXParameters pkixParamsTrust; KeyStore keyStore; FileInputStream keyStream = null; File keystoreFile; // java.security.cert.PKIXParameters for the keyStore PKIXParameters pkixParamsKey; try { trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); truststoreFile = new File(TRUSTSTORE_FILE); keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keystoreFile = new File(KEYSTORE_FILE); try { trustStream = new FileInputStream(truststoreFile); keyStream = new FileInputStream(keystoreFile); } catch (FileNotFoundException ex) { Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex); } try { trustStore.load(trustStream, PASSWORD.toCharArray()); keyStore.load(keyStream, PASSWORD.toCharArray()); } catch (IOException ex) { Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex); } catch (CertificateException ex) { Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex); } try { pkixParamsTrust = new PKIXParameters(trustStore); // accepts Server certificate generated with keytool and (auto) signed by SUN pkixParamsTrust.setPolicyQualifiersRejected(false); } catch (InvalidAlgorithmParameterException ex) { Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex); } try { pkixParamsKey = new PKIXParameters(keyStore); // accepts Client certificate generated with keytool and (auto) signed by SUN pkixParamsKey.setPolicyQualifiersRejected(false); } catch (InvalidAlgorithmParameterException ex) { Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex); } try { sf = new SSLSocketFactory(trustStore); ClientConnectionManager manager = httpclient.getConnectionManager(); manager.getSchemeRegistry().register(new Scheme("https", 3920, sf)); } catch (KeyManagementException ex) { Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex); } catch (UnrecoverableKeyException ex) { Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex); } } catch (NoSuchAlgorithmException ex) { Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex); } catch (KeyStoreException ex) { Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex); } // use the httpclient for any httpRequest return httpclient; }