What are secure SSL Certificate?
Secure SSL certificate is used by most of the websites to prevent private and secure information of their users so that no third party could access them. When an SSL certificate is used, it encrypts the confidential information of users which becomes unreadable and inaccessible for everyone except the server on which information is being passed. SSL certificates binds hostname and organisation identity & location together to create a secure private key.
To initiate a secure session with all browsers, the website owner needs to install the SSL certificate on web server. After installing the certificate, a secure connection is established between the web server and user’s web browser, hence securing all web traffic between the two.
After successful installation of certificate, the application protocol changes from HTTP to HTTPS symbolizing the secure connection created between web browser and server.
What are self-signed certificates?
Self-signed certificate is an identity certificate which is signed by its own creator. Technically, a self-signed certificate is one signed by its own private key. The Signature provides a trust warning while accessing the self-signed website that there was a non-verified publisher.
In order to avoid cost of buying an SSL certificate from a publicly-trusted CA, some website owners decide to use self-signed certificate.
Reason for SSLHandshakeException:
There could be many situations where the server throws SSLHandshakeException such as, when a secure SSL certificate owned by a website gets expired and due to this, the web server denies to accept any request from the website to avoid breach of any secure information. In this case, the web server throws following exception:
avax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1916)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:279)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:273)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1472)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:213)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:913)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:849)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1035)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1344)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1371)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1355)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:275)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:254)
at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:123)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:318)
Solution:
While creating an Httpclient for the website, below code is used:
CloseableHttpClient httpClient=null; httpClient = HttpClients.createDefault();
The above two lines only work for secure SSL certified websites. If your site uses self-signed certificate, use below code instead of above two lines.
CloseableHttpClient httpClient=null; //Builder for SSLContext instances SSLContextBuilder builder = new SSLContextBuilder(); builder.loadTrustMaterial(null, new TrustSelfSignedStrategy()); //create SSL connection Socket Factory object for trusting self-signed certificates SSLConnectionSocketFactory sslcsf = new SSLConnectionSocketFactory( builder.build()); httpClient = HttpClients.custom().setSSLSocketFactory(sslcsf).build();