HttpGet with HTTPS : SSLPeerUnverifiedException
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.
- Import a trusted certificate and generate a truststore file
keytool -import -alias "my server cert" -file server.crt -keystore my.truststore
- Generate a new key (use the same password as the truststore)
keytool -genkey -v -alias "my client key" -validity 365 -keystore my.keystore
- Issue a certificate signing request (CSR)
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
- Import the PKCS#7 file containg the complete certificate chain
keytool -import -alias "my client key" -file mycert.p7 -keystore my.keystore
- Verify the resultant keystore file's contents
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.keystorekeytool -export -alias server-alias -storepass changeit -file server.crt -keystore my.keystore
Using HttpClient 3.x, you need to do this:
Protocol easyHttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443);Protocol.registerProtocol("https", easyHttps);
An implementation of EasySSLProtocolSocketFactory can be found here.