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

标签 java php ssl ssl-certificate java-security

我尝试使用 Java 从“https://api.softtouch.eu/#/xxxxxxxx/#/customers?take=100”检索数据。

我还尝试使用以下选项解决 https 的问题:-

  1. 使用 Java key 工具将证书(.pem 扩展文件)添加到 keystore ($JAVA_HOME/jre/lib/security/cacerts)

  2. 使用 update-ca-certificates 命令向 Ubuntu (/usr/local/share/ca-certificates) 添加了证书颁发机构。

  3. 最后尝试禁用证书验证并连接到服务器。 (此处为 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.2 RandomCookie:GMT:1425473345 字节 = { 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:{} 密码套件:[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_EC DH_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] 压缩方法:{ 0 } 扩展 elliptic_curves,曲线名称:{secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect57 1k1、sect571r1、secp160k1、secp160r1、secp160r2、secp163r1、secp192k1、secp193r1、secp193r2 , secp224k1, secp239k1, secp256k1} 扩展 ec_point_formats,格式:[未压缩] 扩展signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA224withECDSA, SHA224withRSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA, MD5withRSA


主要,写入:TLSv1.2 握手,长度 = 195 主要,阅读:TLSv1.2 警报,长度 = 2 主要,RECV TLSv1.2 警报:致命,握手失败 主要,调用 closeSocket()

最佳答案

该站点的证书没有问题,因此您无需禁用证书验证。但是,该站点需要使用 Server Name Indication (SNI)出示正确的证书。是否支持 SNI 取决于 Java 版本,是否启用取决于 Java 版本,但它不适用于 Java 1.6 及更低版本。

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

关于java - 尝试使用 Java 连接 https 服务器时抛出 SSLHandshakeException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32579299/

相关文章:

PHP MYSQL 事件监听器

PHP - 具有相对路径的 include() 或 require() 在 Windows 上不起作用,即使在附加 __DIR__ 时也是如此

php - 通过 PHP 获取 MySQL 数据库输出到 XML

java - spring MongoRepository 查询正则表达式

java - 在Java中,如何使用在程序其他位置的try/catch block 内初始化的变量?

ruby - 使用 SSL 通过 Ruby 驱动程序连接到 Mongod 返回 Mongo::ConnectionFailure

ssl - 使用 Apache 和 Windows 通过 HTTP 推送我的 Mercurial 存储库

iis - 在 IIS 下使用 SSL 的多个子域

java - 找到 vector 的最小值并分配相应的字符串

java - Google App Engine 上的 CPU 带宽是太贵了还是我的代码?