HttpGet with HTTPS : SSLPeerUnverifiedException
Solution 1
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.
Solution 2
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;
}
}
Solution 3
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.keystore
keytool -export -alias server-alias -storepass changeit
-file server.crt -keystore my.keystore
Solution 4
This exception will come in case your server is based on JDK 7 and your client is on JDK 6 and using SSL certificates. In JDK 7 sslv2hello message handshaking is disabled by default while in JDK 6 sslv2hello message handshaking is enabled. For this reason when your client trying to connect server then a sslv2hello message will be sent towards server and due to sslv2hello message disable you will get this exception. To solve this either you have to move your client to JDK 7 or you have to use 6u91 version of JDK. But to get this version of JDK you have to get the
Stefan Kendall
Updated on August 02, 2022Comments
-
Stefan Kendall almost 2 years
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?
-
Stefan Kendall almost 13 yearsUpdated URL. All you really need to do is google
EasySSLProtocolSocketFactory
. The exact string is so specific that it seemed like there were no bad results. -
Bruno about 12 yearsIt should be noted that this method does exactly what the question asks for: it supresses the error message. It doesn't actually solve the problem since the connection is insecure. The right way would be to import the remote certificate explictly in your trust store.
-
Maarten Bodewes over 11 yearsAnd again, for anybody that is interested in security, this does not fix the underlying problem. Import the certificate in your certificate store, but don't trust all connections as you might as well not use SSL.
-
Jonas Andersson over 11 yearsOf course. Doing the above in production code would be incredibly counter productive. But if you don't care about security, for example in an end-to-end test against a development server, it's nice to not depend on the server certs.
-
Maarten Bodewes over 11 yearsThanks for the edit, it never hurts to make that kind of security warning explicit.
-
dalvarezmartinez1 over 10 years@owlstead "you might as well not use SSL" I use SSL only for encryption, not for authenticating the server to the client, how is this not safe?
-
Jonas Andersson over 10 yearsI assume your purpose for using encryption is preventing man-in-the-middle to read your data. If so, without authenticating the cert, you don't know who is at the other end, it could be the man-in-the-middle proxying the communication, i.e. decrypting it, reading it, encrypting it, passing it on. You'll never know...
-
daiscog over 9 yearsIt's worth noting that steps 2-7 are only required if you need to implement client authentication, too (i.e., letting the server authenticate the client). In most cases, step 1 alone will be enough.
-
cheftao over 8 yearshow do i create the server.crt?
-
Barett over 8 yearsEdited to include server.crt creation steps.
-
Steven Schlansker almost 6 yearsThis doesn't fix the problem, and the link leads to a parked page :/