dongzha0149
dongzha0149
2015-09-15 06:38

尝试使用Java连接https服务器时抛出SSLHandshakeException

已采纳

I tried to retrieve data from "https://api.softtouch.eu/#/xxxxxxxx/#/customers?take=100" using Java.

Also I tried to fix the problem with https using following options:-

  1. Added certificate (.pem extension file) to the keystore ($JAVA_HOME/jre/lib/security/cacerts) using Java keytool

  2. Added certificate authority to Ubuntu (/usr/local/share/ca-certificates) using update-ca-certificates command.

  3. Finally tried to disable the certificate validation and connect to the server. (SoftTouchConnection class and custom TrustAllX509TrustManager class here.)

    package com.softtouch.com;
    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.net.URL;
    import java.security.Security;
    
    import javax.net.ssl.HostnameVerifier;
    import javax.net.ssl.HttpsURLConnection;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLSession;
    import javax.net.ssl.TrustManager;
    
    import org.apache.commons.codec.binary.Base64;
    
    public class SoftTouchConnection {
      public static void main(String[] args) {
        try {           
    
        System.out.println(System.getProperty("java.version"));
        System.setProperty("javax.net.debug", "ssl");
        System.setProperty("sun.net.ssl.checkRevocation", "false"); 
           java.lang.System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true");
        Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
        SSLContext sc = SSLContext.getInstance("SSL");//TLSv1.2
        sc.init(null, new TrustManager[] {new TrustAllX509TrustManager() }, null);//new java.security.SecureRandom()
    
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
    
            @Override
            public boolean verify(String string, SSLSession ssls) {                 
                System.out.println("test HttpsURLConnection");
                return true;
            }           
        });
    
        String userCredentialsnew = "abcdefghij01234567890klmnopqrstuvwxyz987";//"bearer abcdefghij01234567890klmnopqrstuvwxyz987";
        String basicAuth = "Basic "+ new String(new Base64().encode(userCredentialsnew.getBytes()));; //+ new String(new Base64().encode(userCredentials.getBytes()));
        URL hh= new URL("https://api.softtouch.eu/#/xxxxxxxx/#/customers?take=100");
        HttpsURLConnection conn = (HttpsURLConnection)hh.openConnection();
    
    
        conn.setSSLSocketFactory(sc.getSocketFactory());
        conn.setHostnameVerifier( new HostnameVerifier() {
    
            @Override
            public boolean verify(String string, SSLSession ssls) {             
                System.out.println("test conn");
                return true;
            }           
        });         
    
        conn.setDoInput(true);
        conn.setDoOutput(false);
        conn.setUseCaches(false);
        conn.setRequestMethod("GET");           
        conn.setRequestProperty ("Authorization", basicAuth);       
        conn.connect();
    
    
        BufferedReader inn = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String inputLine;          
        while ((inputLine = inn.readLine()) != null) {
            System.out.println(inputLine);
        }         
    
       } catch (Exception e) {
          e.printStackTrace();
       }
    
      }
     }
    
    
    
    package com.softtouch.com;
    
    import javax.net.ssl.X509TrustManager;
    
    import java.security.cert.X509Certificate;
    
    
    
    public class TrustAllX509TrustManager implements X509TrustManager {
      public X509Certificate[] getAcceptedIssuers() {
        System.out.println("test1");
        //return new X509Certificate[0];
        return null;
     }
    
      public void checkClientTrusted(java.security.cert.X509Certificate[] certs,String authType) {
       System.out.println("test2");
     }
    
     public void checkServerTrusted(java.security.cert.X509Certificate[] certs,String authType) {
       System.out.println("test3");
     }
    
    }
    

But so far I could not solve the problem. I received the"javax.net.ssl.SSLHandshakeException". I want connect to the server using Java. What will be the reason for this issue?

Note:- I tested "https://api.softtouch.eu/#/accounts/#/xxxxxxxx?take=100" connection with PHP. It is working well. But PHP source file has used following line to disable the SSL verification. curl_setopt($httpRequest, CURLOPT_SSL_VERIFYPEER, FALSE);

This is the SSL debug text:- *** ClientHello, TLSv1.2 RandomCookie: GMT: 1425473345 bytes = { 113, 222, 27, 25, 227, 136, 38, 249, 128, 230, 125, 228, 156, 5, 175, 99, 22, 55, 227, 185, 101, 32, 160, 186, 72, 167, 247, 166 } Session ID: {} Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV] Compression Methods: { 0 } Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1} Extension ec_point_formats, formats: [uncompressed] Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA224withECDSA, SHA224withRSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA, MD5withRSA


main, WRITE: TLSv1.2 Handshake, length = 195 main, READ: TLSv1.2 Alert, length = 2 main, RECV TLSv1.2 ALERT: fatal, handshake_failure main, called closeSocket()

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

1条回答

  • dtpngq3378499 dtpngq3378499 6年前

    The certificate for the site is fine so you don't need to disable certificate validation. But, the site requires the use of Server Name Indication (SNI) to present the correct certificate. If SNI is supported depends and if it is enabled depends on the Java version, but it is not available with Java 1.6 and lower.

    Apart from that the Handshake Exception might indicate that the problem is not related to certificate validation at all. The site only supports a few ciphers which all use AES256. But support for AES256 is not available in Java by default because of export restrictions.

    点赞 评论 复制链接分享