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


Throw SSLHandshakeException when try to connect https server using Java

我试图从"https://api.softtouch.eu/#/xxxxxxxx/#/customers?使用Java的take=100。

我也试图解决问题与https使用以下选项:-

  1. 新增证书(。使用Java keytool

  2. 将密钥存储库($JAVA_HOME/jre/lib/security/cacerts)拷贝到密钥存储库($JAVA_HOME/jre/lib/security/cacerts)
  3. 使用update-ca-certificates命令为Ubuntu (/usr/local/share/ca-certificates)添加证书颁发机构

  4. 最后尝试禁用证书验证并连接到服务器。(SoftTouchConnection类和自定义TrustAllX509TrustManager类在这里)

    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");
     }
    }
    

但是到目前为止我还不能解决这个问题。我收到了"javax.net.ssl.SSLHandshakeException"。我想用Java连接到服务器。这个问题的原因是什么?

注意:-我测试了"https://api.softtouch.eu/#/accounts/#/xxxxxxxx?take=100"连接到PHP。它运行得很好。但是PHP源文件使用了下面一行来禁用SSL验证。curl_setopt($httpRequest, CURLOPT_SSL_VERIFYPEER, FALSE);

SSL调试文本:-*** ClientHello, TLSv1.2RandomCookie: 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}会话ID: {}密码套件:[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_rsa_with_aes_128_cbc_sha256, tls_dhe_rsa_with_aes_128_cbc_sha256, tls_ecdhe_ecdsa_with_aes_128_cbc_sha256, tls_ecdhe_ecdsa_with_aes_128_cbc_sha, tls_rsa_with_aes_128_cbc_sha, tls_ecdh_ecdsa_with_aes_128_cbc_sha, tls_ecdh_ecdsa_with_aes_128_cbc_sha, tls_ecdh_ecdsa_with_aes_128_cbc_sha, tls_ecdh_rsa_with_aes_128_cbc_sha, tls_ecdh_rsa_with_aes_128_cbc_sha, tls_ecdh_rsa_with_aes_128_cbc_sha, tls_ecdh_rsa_with_aes_128_cbc_sha, tls_ecdh_rsa_with_aes_128_cbc_sha, tls_ecdh_rsa_with_aes_128_cbc_sha, tls_ecdh_rsa_with_aes_128_cbc_sha, tls_ecdh_rsa_with_aes_128_cbc_sha, tls_ecdh_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]压缩方法:{0}扩展椭圆曲线,曲线名称:{secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, secp163r1, secp192k1, sect239k1, secp256k1}扩展ec_point_formats,格式:[未压缩]扩展signature_algorithms, signature_algorithms: SHA512withECDSA, sha512withthsa, SHA384withECDSA, sha384withthrsa, SHA256withECDSA, sha256withthsa, SHA224withECDSA, sha224withthsa, SHA1withECDSA, sha1withthsa, sha1withthsa, sha1withthsa, sha1withthsa, sha1withthsa, md5withthrsa


main, WRITE: TLSv1.2 Handshake, length = 195main, READ: TLSv1.2 Alert, length = 2警告:fatal, handshake_failuremain,称为closeSocket()

该站点的证书很好,所以您不需要禁用证书验证。但是,站点需要使用服务器名称指示(SNI)来提供正确的证书。是否支持SNI取决于Java版本,是否启用SNI取决于Java版本,但在Java 1.6及更低版本中不可用。

除此之外,握手异常可能表明问题根本与证书验证无关。该网站只支持几个使用AES256的密码。但是由于导出限制,默认情况下Java中不支持AES256。