0

I am attempting to write a Java https client (Using HttpsURLConnection) using jdk version 1.6.0_29. I then Imported the certificate /wlserver_10.3/server/lib/CertGenCA.der to the keystore of the client. by following command:

keytool -import -alias test -keystore "D:\Program Files\Java\jdk1.6.0_29\jre\lib\security\cacerts" -file CertGenCA.der

The issue is that I keep getting "Exception in thread "main" javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake" The SSL debug output is as follows:

           keyStore is : 
           keyStore type is : 
           jks keyStore provider is : 
           init keystore

           init keymanager of type SunX509
           trustStore is: D:\Program Files\Java\jdk1.6.0_29\jre\lib\security\cacerts
           trustStore type is : jks
           trustStore provider is : 
           init truststore
enter code here
adding as trusted cert:
Subject: CN=SwissSign Platinum CA - G2, O=SwissSign AG, C=CH
Issuer:  CN=SwissSign Platinum CA - G2, O=SwissSign AG, C=CH 
Algorithm: RSA; Serial number: 0x4eb200670c035d4f 
Valid from Wed Oct 25 04:36:00 VET 2006 until Sat Oct 25 04:06:00 VET 2036



adding as trusted cert:
Subject: EMAILADDRESS=info@valicert.com, CN=http://www.valicert.com/, OU=ValiCert Class    1 Policy Validation Authority, O="ValiCert, Inc.", L=ValiCert Validation Network

Issuer: EMAILADDRESS=info@valicert.com, CN=http://www.valicert.com/, OU=ValiCert Class 1 Policy Validation Authority, O="ValiCert, Inc.", L=ValiCert Validation Network Algorithm: RSA; Serial number: 0x1 Valid from Fri Jun 25 18:23:48 VET 1999 until Tue Jun 25 17:53:48 VET 2019

.. .. ..

            trigger seeding of SecureRandom
            done seeding SecureRandom

            Allow unsafe renegotiation: false 
            Allow legacy hello messages: true 
            Is initial handshake: true 
            Is secure renegotiation: false 

            %% No cached client session 
            *** ClientHello, SSLv3 
            RandomCookie:  GMT: 1362670800 bytes = { 77, 1, 89, 245, 75, 245, 125, 199, 168, 78, 33, 255, 83, 57, 65, 228, 118, 11, 240, 48, 210, 7, 245, 45, 70, 153, 149, 149 }


            Session ID:  {} 
            Cipher Suites: [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]

              Compression Methods:  { 0 } 
              *** 
              main, WRITE: SSLv3 Handshake, length = 75 
              main, received EOFException: error 
              Exception in thread "main" javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake 

main, handling exception: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake

              main, SEND TLSv1 ALERT:  fatal, description = handshake_failure
              main, WRITE: TLSv1 Alert, length = 2 
              main, called closeSocket()

main, called close() main, called closeInternal(true) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:849)

.. ..

               Caused by: java.io.EOFException: SSL peer shut down incorrectly
               at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:333)
               at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:830)
... 7 more

Not sure how to interpret all of this information

My code is run from Eclipse and URL (JAX-WS) it is hitting is on the LAB and in solaris box

My test client code is as follows:


URL wsdlLocation = new URL("https://server.lab.ciso.com:8833/Impl/Service?wsdl");

    System.setProperty("weblogic.security.SSL.ignoreHostnameVerification", "true");
    System.setProperty("javax.net.ssl.trustStore", "D:\\Program Files\\Java\\jdk1.6.0_29\\jre\\lib\\security\\cacerts");
    System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
    System.setProperty("https.protocols", "SSLv3");

    SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();

    HttpsURLConnection conn = null;
    try {
        conn = (HttpsURLConnection) wsdlLocation.openConnection();
        conn.setSSLSocketFactory(sslsocketfactory);
        conn.setDoOutput(true);
        conn.setUseCaches(false);
        conn.setRequestMethod("GET");
        conn.setRequestProperty("Content-Type","application/Json");
        conn.setDoInput(true);
        conn.connect();
        BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        StringBuilder sb = new StringBuilder();
        String line;
        while ( ((line = br.readLine()) != null)) {
            if((line.indexOf("wsp:PolicyReference") == -1))
                sb.append(line+"\n");
        }
        br.close();
        System.out.println("Random code::"+sb.toString());

    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }

user2040528
  • 11
  • 1
  • 6

1 Answers1

0

First of all modifying the cacerts truststore of an JDK installation is very bad practice, as you will loose the modification with an JDK update that currently are released about once a week because of vulnerabilities.

If you want to use a modified Java truststore copy it into your project and modify/use it from there.

The main problem (I assume) of your code is that you are limiting the protocols to SSLv3 using the following call: System.setProperty("https.protocols", "SSLv3");.

SSL3 is very old and insecure in certain situations, therefore you should use TLS v1.0 or higher. If the server is limited to TLS (which seems to be the case here) your connection will fail.

Therefore change "SSLv3" it to "TLSv1" or "TLSv1.1" ("TLSv1.2" is AFAIR only supported by Java 7).

Robert
  • 39,162
  • 17
  • 99
  • 152
  • Thanks for quick response, yes i agree that modifying JDK's cert was a bad idea :-( Earlier i was trying with wrong port (my BAD) now i have a correct SSL port to connect to and also commented below line: 'System.setProperty("https.protocols", "SSLv3");' now i'm getting this error: 'main, SEND TLSv1 ALERT: fatal, description = certificate_unknown main, WRITE: TLSv1 Alert, length = 2 main, called closeSocket() main, handling exception: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching server.lab.cisco.com found' pls advise!!! – user2040528 Mar 08 '13 at 14:17
  • Are you sure that the cert you are using on server side was issued for the dns name `server.lab.ciso.com`? – Robert Mar 08 '13 at 14:27
  • my server side is WL 10.3 i have copied below file in order to generate keyStore: /wlserver_10.3/server/lib/CertGenCA.der I'm going to attach two snap-shots from SSL and KeyStore tabs of my server in WL, then would you be able to tell which one to use? – user2040528 Mar 08 '13 at 14:34
  • how to attach a file in this site?? :-( – user2040528 Mar 08 '13 at 14:42
  • Ok, so since 'config.xml' of WL server does not have trusted CA certificates specified that means it uses DemoTrust As mentioned above i used DemoTrust.jks but no lock :-( what is missed here ??? – user2040528 Mar 08 '13 at 15:17
  • Tried this below code with DemoTrust.jks but no luck: `URL wsdlLocation = new URL("https://server.lab.cisco.com:8844/Impl/Service?wsdl"); System.setProperty("weblogic.security.SSL.ignoreHostnameVerification", "true"); System.setProperty("javax.net.ssl.trustStore", "D:\\Program Files\\Java\\jdk1.6.0_29\\DemoTrust.jks"); HttpsURLConnection conn = (HttpsURLConnection) wsdlLocation.openConnection(); conn.connect();` Still get: : javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching server.lab.cisco.com found – user2040528 Mar 08 '13 at 15:35
  • Please read http://stackoverflow.com/questions/3093112/certificateexception-no-name-matching-ssl-someurl-de-found – Robert Mar 08 '13 at 15:44
  • No Matter what i try i always get `No name matching server.lab.cisco.com found` From SSL debug log if you see i get CN as "server" instead of "server.lab.cisco.com" .... how to fix this?? `Certificate chain chain [0] = [ [ Version: V1 Subject: CN=server, OU=FOR TESTING ONLY, O=MyOrganization, L=MyTown, ST=MyState, C=US` – user2040528 Mar 08 '13 at 17:05
  • Only way to fix this is to bypass Hostname verification, as shown below: `HostnameVerifier hv = new HostnameVerifier() { public boolean verify(String urlHostName, SSLSession session) { System.out.println("Warning: URL Host: " + urlHostName + " vs. " + session.getPeerHost()); return true; } }; HttpsURLConnection conn = (HttpsURLConnection) wsdlLocation.openConnection(); conn.setHostnameVerifier(hv); – user2040528 Mar 08 '13 at 17:37
  • But not sure if this is right to do Alternatively, i do have control over the server i'm connecting to and its certificate, but how can i create a certificate of it that matches the naming rules above i.e be sure that common name (CN) is the host name i'm trying to talk to?? – user2040528 Mar 08 '13 at 17:45
  • If `HostnameVerifier` always return true then my program always works fine and get connected via HTTPS even if i don't pass the certificate. Isn't it wrong?? – user2040528 Mar 09 '13 at 08:34