Making HTTPS Request and opening SSL socket in JAVA


Question

I am trying to build a login page. For that, I want to open a SSL socket and make a HTTPS request,but im getting Unknown Host Exception in line-- SSLSocket skt = (SSLSocket)sslsf.createSocket("https://31.21.18.222/room_info/x.txt" , 443); Could someone please tell me what Im doing wrong? Also, i`ve turned off host verification because it wont be needed in my program.

`public void clickLogin() throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException {


            URL url = new URL ("https://31.21.18.222/room_info/x.txt");
            HttpsURLConnection connection = null;
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null);        //Make an empty store
            InputStream fis = new FileInputStream("C:/Documents and Settings/user/Desktop/PK/localhost.crt"); 
            BufferedInputStream bis = new BufferedInputStream(fis);
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            while (bis.available() > 0) {
                java.security.cert.Certificate cert = cf.generateCertificate(bis);
                keyStore.setCertificateEntry("localhost", cert);
            }

            // write code for turning off client verification
            TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
            tmf.init(keyStore);
            SSLContext context = SSLContext.getInstance("SSL");
            context.init(null, tmf.getTrustManagers() , null);
            Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
            SSLSocketFactory sslsf = context.getSocketFactory();
            SSLSocket skt = (SSLSocket)sslsf.createSocket("https://31.21.18.222/room_info/x.txt" , 443);
            skt.setUseClientMode(true);
            SSLSession s = skt.getSession(); // handshake implicitly done
            skt.setKeepAlive(true);


            connection = (HttpsURLConnection) url.openConnection();

        // Host name verification off
            connection.setHostnameVerifier(new HostnameVerifier()  
            {        
                public boolean verify(String hostname, SSLSession session)  
                {  
                    return true;  
                }  
            });  `
1
4
6/26/2013 9:26:01 AM

Accepted Answer

If you want to open a socket with createSocket, you need to use the host name (or IP address), not the full URL:

example : sslsf.createSocket("31.21.18.222" , 443);

In addition:

  • Don't use Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider()) (it's there by default).
  • It's probably better to use TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()) instead of X.509, especially because the default algorithm for the TMF is PKIX, not X.509.
  • createSocket will verify the certificate against the trust anchors, but won't check the host name (which is also required to prevent MITM attacks). For this, it's also generally better to use a host name instead of an IP address.
2
11/12/2013 1:02:51 PM

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon