java.io.IOException: HTTPS hostname wrong: should be <blah blah>

Hi There,
I Have a url which i run in IE and its returns results as expected.  However, when i try and open a connection via my java class running over the command line it returns the following error:

java.io.IOException: HTTPS hostname wrong:  should be <blah blah>
I believe it may be related to certificates, how can i fix this error?

For reference here's my code thus far:

package peewee;

import java.io.InputStream;
import java.net.URL;
import java.lang.StringBuffer;

public class Test {

      public static void main(String[] args) {
            
            
            final String HOST       = "https://blah";
            final String SUFFIX       = "blah";
                        
            try {
                   URL url = new URL(HOST + SUFFIX);
                   javax.net.ssl.HttpsURLConnection conn = null;
                             conn = (javax.net.ssl.HttpsURLConnection) url.openConnection();
                             conn.setRequestMethod("GET");

              InputStream input             = conn.getInputStream();
                StringBuffer buff             = new StringBuffer();
                  
                  int c;
                  while ( ( c = input.read() ) != -1 ) {
                        buff.append((char) c);
                  }
                  System.out.println("total " + buff.toString() );
                  
            }
            catch ( Exception e ) {
                  System.out.println("error:" + e.toString());
                  
            }
            
      }
}

LVL 5
PeeweeAsked:
Who is Participating?
 
aozarovConnect With a Mentor Commented:
You can try the solution provided in this thread (the last one): http://forum.java.sun.com/thread.jspa?threadID=521779&tstart=75
which also adds its own TrustManager
0
 
TimYatesCommented:
>> java.io.IOException: HTTPS hostname wrong:  should be <blah blah>

what is the actual error?  I assume it doesn't actually say "blah blah"

Does the host do a dynamic redirection to the actual host machine?

What line throws the exception?
0
 
bloodredsunCommented:
From a quick dig around I found this as a solution:

This happens if the hostname in the URL does not match the hostname in the certificate. There is an easy workaround to this: you have to define your own hostname verifier and configure the HttpsURLConnection with it:

HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
    public boolean verify(String urlHostname, String certHostname) {
        return true;
    }
});

0
Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

 
neonlinesProject managerCommented:
I think u r getting java.io.IOException in the following line only
>> InputStream input           = conn.getInputStream();

Just copy ur HOST + SUFFIX and put a browser and check it's a correct URL or not

If it is correct URL, then u ll not get IO Exception

But, any way change the line

>>  URL url = new URL(HOST + SUFFIX);

as

com.sun.net.ssl.internal.ssl.Provider.install();
java.security.Security.insertProviderAt(new com.sun.net.ssl.internal.ssl.Provider(), 1);

URL url = new URL(null, HOST + SUFFIX, new com.sun.net.ssl.internal.www.protocol.https.Handler());


0
 
neonlinesProject managerCommented:
Change the line

>>  conn.setRequestMethod("GET");

as

conn.setRequestMethod("POST");
0
 
neonlinesProject managerCommented:
I Changed ur Test program and check this

I hope, u added ur certificate in cacerts already

import java.io.InputStream;
import java.net.URL;
import java.lang.StringBuffer;

public class Test {

     public static void main(String[] args) {
         
         
          final String HOST       = "https://blah";
          final String SUFFIX      = "blah";
                   
          try {
            com.sun.net.ssl.internal.ssl.Provider.install();
            java.security.Security.insertProviderAt(new com.sun.net.ssl.internal.ssl.Provider(), 1);

            URL url = new URL(null, HOST + SUFFIX, new com.sun.net.ssl.internal.www.protocol.https.Handler());
                 javax.net.ssl.HttpsURLConnection conn = null;
                 conn = (javax.net.ssl.HttpsURLConnection) url.openConnection();
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod("POST");
            conn.setFollowRedirects(true);

            
             BufferedReader in           = new BufferedReader(new  InputStreamReader(conn.getInputStream()));
               StringBuffer buff           = new StringBuffer();
               
            String inputLine = null;
            while ((inputLine = in.readLine()) != null)
            {
                  System.out.println(inputLine);
            }
               
          }
          catch ( Exception e ) {
               System.out.println("error:" + e.toString());
               
          }
         
     }
}

0
 
aozarovCommented:
Peewee,
Your program worked fine for me as is (replacing https://blahblah with www.google.com)
BTW, did mean to have SUFFIX   as "/blah" ? do you want https://blah/blah or https://blahblah ?
Older JVM have some certificates in their certificate tree expired (So you might want to upgrade it or your JVM)
If you are accessing a site that self signed or uses a certificate which is not part of your certificate tree then you
will see exception similar to:
error:javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.sec
urity.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
0
 
PeeweeAuthor Commented:
Hi neon lines,
i thought i'd respond to you first as you've put the most detail and effort into your posting.  Thanks for your code, I've tried to use it, but ecplise reports the following error:

java.lang.ClassCastException: com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnectionOldImpl

I've ammended it slightly to:
import java.net.URL;
import java.lang.StringBuffer;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class EETest {

     public static void main(String[] args) {
         
         
          final String HOST       = "http://www.google.com";
          final String SUFFIX     = "";
                   
          try {
          com.sun.net.ssl.internal.ssl.Provider.install();
          java.security.Security.insertProviderAt(new com.sun.net.ssl.internal.ssl.Provider(), 1);

          URL url = new URL(null, HOST + SUFFIX, new com.sun.net.ssl.internal.www.protocol.https.Handler());
                 javax.net.ssl.HttpsURLConnection conn = null;
                 conn = (javax.net.ssl.HttpsURLConnection) url.openConnection();
          conn.setDoInput(true);
          conn.setDoOutput(true);
          conn.setUseCaches(false);
          conn.setRequestMethod("POST");
          conn.setFollowRedirects(true);

         
          BufferedReader in           = new BufferedReader(new  InputStreamReader(conn.getInputStream()));
          StringBuffer buff           = new StringBuffer();
               
          String inputLine = null;
          while ((inputLine = in.readLine()) != null)
          {
               System.out.println(inputLine);
          }
               
          }
          catch ( Exception e ) {
               System.out.println("error:" + e.toString());
               
          }
         
     }
}

 
0
 
PeeweeAuthor Commented:
Hi bloodredsun,
thanks for your comment, i've seen postings on the web talking about your approach, however i'm unable to get the code to successfully integrate into mine, can you ammend my code with your insert..

thanks pg
0
 
aozarovCommented:
I think this is what bloodredsun meant:

// add after conn = (javax.net.ssl.HttpsURLConnection) url.openConnection();

conn.setDefaultHostnameVerifier(new javax.net.ssl.HostnameVerifier() {
    public boolean verify(String urlHostname, String certHostname) {
        return true;
    }

    public boolean verify(String urlHostname, javax.net.ssl.SSLSession session) {
        return true;
    }
});
..

But I don't think it should help in your case
0
 
neonlinesProject managerCommented:
>> but ecplise reports the following error:

>> java.lang.ClassCastException:

Yes, I used javax.net.ssl.HttpsURLConnection (which is Java own package) and ur ecplise needs a class as
com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnection

Change the corresponding Object usage with respect to ecplise

I think u ll face some more problem bcaz of ecplise. Bcaz ecplise also having it's own defined class for HTTPS and Java also having it's and I think u included both in ur classpath

U remove either ecplise packages or Java include packages and try

I think u have to do a lot




0
 
PeeweeAuthor Commented:
bloodredsun & aozarov,
i have added the code you suggested but i am still getting the same error.

any thoughts
0
 
aozarovCommented:
What is the error you are getting?
0
 
PeeweeAuthor Commented:
hi aozarov,
its the same error:

java.io.IOException: HTTPS hostname wrong:  should be <blah blah>
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.