dongzha0149 2015-09-15 06:38
浏览 407
已采纳

尝试使用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 2015-09-15 07:52
    关注

    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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 有没有帮写代码做实验仿真的
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥30 vmware exsi重置后登不上
  • ¥15 易盾点选的cb参数怎么解啊
  • ¥15 MATLAB运行显示错误,如何解决?
  • ¥15 c++头文件不能识别CDialog
  • ¥15 Excel发现不可读取的内容
  • ¥15 关于#stm32#的问题:CANOpen的PDO同步传输问题
  • ¥20 yolov5自定义Prune报错,如何解决?