Using HttpClient, I receive the following error when attempting to communicate over HTTPS:
Exception in thread "main" javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated.
Here is my code:
URI loginUri = new URI("https://myUrl.asp"); HttpClient httpclient = new DefaultHttpClient(); HttpGet httpget = new HttpGet( loginUri ); HttpResponse response = httpclient.execute( httpget );
How do I suppress or remove this error?
Note: Do not do this in production code, use http instead, or the actual self signed public key as suggested above.
On 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; } }
This answer follows on to owlstead and Mat's responses. It applies to SE/EE installations, not ME/mobile/Android SSL.
Since no one has yet mentioned it, I'll mention the "production way" to fix this: Follow the steps from the AuthSSLProtocolSocketFactory class in HttpClient to update your trust store & key stores.
keytool -import -alias "my server cert" -file server.crt -keystore my.truststore
keytool -genkey -v -alias "my client key" -validity 365 -keystore my.keystore
keytool -certreq -alias "my client key" -file mycertreq.csr -keystore my.keystore
(self-sign or get your cert signed)
Import the trusted CA root certificate
keytool -import -alias "my trusted ca" -file caroot.crt -keystore my.keystore
keytool -import -alias "my client key" -file mycert.p7 -keystore my.keystore
keytool -list -v -keystore my.keystore
If you don't have a server certificate, generate one in JKS format, then export it as a CRT file. Source: keytool documentation
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With