2015-07-19 57 views
1

我是新来的任何网络相关的编程,所以我知道我在深潜,但我必须让我的Android HttpsURLConnection的之间的成功SSL握手的问题我本地的XAMPP托管网站,而不仅仅是一个返回Hello World的PHP脚本!让我先说,我可以从我的电脑(主机),并从我的Android手机浏览器( HTTPS)加载这个页面。在SSL库的Android未能连接到我的本地XAMPP当托管网站

问题:

当我尝试应用与我的服务器通过HttpsURLConnection的我碰到下面的错误连接:

System.err﹕ javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x5e522ba8: Failure in SSL library, usually a protocol error 
System.err﹕ error:1407743E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert inappropriate fallback (external/openssl/ssl/s23_clnt.c:744 0x5e5967e8:0x00000000) 
System.err﹕ at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:449) 
System.err﹕ at com.android.okhttp.Connection.upgradeToTls(Connection.java:146) 
System.err﹕ at com.android.okhttp.Connection.connect(Connection.java:107) 
System.err﹕ at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:294) 
System.err﹕ at com.android.okhttp.internal.http.HttpEngine.sendSocketRequest(HttpEngine.java:255) 
System.err﹕ at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:206) 
System.err﹕ at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:345) 
System.err﹕ at com.android.okhttp.internal.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:89) 
System.err﹕ at com.android.okhttp.internal.http.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:161) 
System.err﹕ at yellowgames.battlenetfriendfinder.ServerConnection$TaskExecuter.doInBackground(ServerConnection.java:118) 
System.err﹕ at yellowgames.battlenetfriendfinder.ServerConnection$TaskExecuter.doInBackground(ServerConnection.java:94) 
System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:288) 
System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
System.err﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 
System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
System.err﹕ at java.lang.Thread.run(Thread.java:841) 
System.err﹕ Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x5e522ba8: Failure in SSL library, usually a protocol error 
System.err﹕ error:1407743E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert inappropriate fallback (external/openssl/ssl/s23_clnt.c:744 0x5e5967e8:0x00000000) 
System.err﹕ at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method) 
System.err﹕ at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:406) 
System.err﹕ ... 16 more 

我的代码:

我的代码在此基础上:https://developer.android.com/training/articles/security-ssl.html

//Get Cert 
try { 
    InputStream CertInputStream = a_sContext.getResources().openRawResource(R.raw.server); 

    //Read Cert 
    CertificateFactory CertFactory = CertificateFactory.getInstance("X.509"); 
    Certificate Cert = CertFactory.generateCertificate(CertInputStream); 
    String Result = "Ca=" + ((X509Certificate) Cert).getSubjectDN(); 
    Log.d("test", Result); //This Returns correct Cert information 

    //Create a keystore 
    KeyStore MyKeyStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
    MyKeyStore.load(null, null); 
    MyKeyStore.setCertificateEntry("ca", Cert); 

    //Create a TrustManager 
    TrustManagerFactory TMF = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
    TMF.init(MyKeyStore); 

    //Create a SSLContext 
    m_pSSLContext = SSLContext.getInstance("TLS"); 
    m_pSSLContext.init(null, TMF.getTrustManagers(), null); 
    HttpsURLConnection.setDefaultSSLSocketFactory(m_pSSLContext.getSocketFactory()); 

    //Try and connect to the website 
    URL MyURL = new URL(m_sSecureHttp + m_sWebsite + m_sTestPath); 
    con = (HttpsURLConnection) MyURL.openConnection(); 
    con.connect(); 
    Result = new String(); 
    BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream()));; 
    while((Line = reader.readLine())!= null) { 
     Result += Line; 
    } 
} 
catch (Exception e) { e.printStackTrace(); } 

服务器端:

我生成以下证书:http://robsnotebook.com/xampp-ssl-encrypt-passwords

这似乎是因为我的本地计算机上工作过和Android浏览器可以访问它。另外,在XAMPP的ssl_request.log中,我可以看到我的本地计算机或我的android浏览器的所有连接尝试,但它甚至没有提到我的应用程序的请求。这对access.log是一样的。

我上的是Android 4.4.2

我的实际问题测试Android应用程序

有谁知道我怎么能解决SSL握手错误?任何提示都很有用!我尝试了很多我可以在谷歌上找到的东西,但目前为止还没有成功。

+0

另外检查:http://stackoverflow.com/questions/29916962/javax-net-ssl-sslhandshakeexception-javax-net-ssl-sslprotocolexception-ssl-han – Chepech

回答

0

上有Android版本4.4.2一个已知的错误正在访问HTTPS使用TLSv1.x协议时引起的。握手会失败,因为不支持TLS那么HttpsURLConnection的回落到的SSLv3协议造成发生在握手的错误。我还没有找到一个解决办法,不涉及重新实现HttpsURLConnection的的TrustManagers防止错误或不安全的连接。

这是我做过什么:

频道自定义信任管理器到您的SSLContext:

// Trust manager that recognizes you acceptance criteria, that being ignoring handshake errors 
     ResourceTrustManager trustManager = new ResourceTrustManager(sslKeyStores); 
     TrustManager[] trustManagers = {trustManager}; 
     // use: org.apache.http.conn.ssl.AllowAllHostnameVerifier, this can be optional depending on your case. 
     AllowAllHostnameVerifier resourceHostNameVerifier = new AllowAllHostnameVerifier(); 

     // Install the trust manager and host name verifier 
     try { 
      SSLContext sc = SSLContext.getInstance("TLS"); 
      sc.init(null, trustManagers, new java.security.SecureRandom()); 
      HttpsURLConnection 
        .setDefaultSSLSocketFactory(sc.getSocketFactory()); 
      HttpsURLConnection.setDefaultHostnameVerifier(resourceHostNameVerifier); 
     } catch (Exception e) { 
      Log.e(TAG, "Invalid algorithm used while setting trust store:" +e.getMessage()); 
      throw e; 
     } 

要实现你的信任管理器只是简单地覆盖:

  • 公共无效checkClientTrusted
  • public void checkServerTrusted

矿使用本地密钥库尝试授权证书:

public class ResourceTrustManager implements X509TrustManager { 

private static final String TAG = ResourceTrustManager.class.getName(); 
protected ArrayList<X509TrustManager> x509TrustManagers = new ArrayList<X509TrustManager>(); 

public ResourceTrustManager(Collection<KeyStore> additionalkeyStores) { 
    final List<TrustManagerFactory> factories = new ArrayList<TrustManagerFactory>(); 

    try { 
     /** 
     * Consolidates central and aditional keystore to be used as trust managers 
     */ 
     final TrustManagerFactory original = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
     original.init((KeyStore) null); 
     factories.add(original); 

     if(additionalkeyStores != null) { 
      for (KeyStore keyStore : additionalkeyStores) { 
       final TrustManagerFactory additionalCerts = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
       additionalCerts.init(keyStore); 
       factories.add(additionalCerts); 
      } 
     } 

    } catch (Exception e) { 
     throw new RuntimeException(e); 
    } 

    for (TrustManagerFactory tmf : factories) { 
     for (TrustManager tm : tmf.getTrustManagers()) { 
      if (tm instanceof X509TrustManager) { 
       x509TrustManagers.add((X509TrustManager) tm); 
      } 
     } 
    } 

    ResourceAssert.hasLength(x509TrustManagers, "Could not initialize with no trust managers"); 

} 

public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { 
    // The default Trustmanager with default keystore 
    final X509TrustManager defaultX509TrustManager = x509TrustManagers.get(0); 
    defaultX509TrustManager.checkClientTrusted(chain, authType); 

} 

public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { 
    for(X509TrustManager tm : x509TrustManagers) { 
     try { 
      tm.checkServerTrusted(chain,authType); 
      return; 
     } catch(CertificateException e) { 
      StringBuilder issuers = new StringBuilder(); 

      if(chain != null){ 
       for(X509Certificate cert :chain){ 
        issuers.append(" " +cert.getIssuerDN().getName()); 
       } 
      } 

      Log.e(TAG, "Untrusted host, connection is not secure "+ issuers + "\n\n" + e.getMessage()); 
     } 
    } 

} 

public X509Certificate[] getAcceptedIssuers() { 
    final ArrayList<X509Certificate> list = new ArrayList<X509Certificate>(); 

    for(X509TrustManager tm : x509TrustManagers) { 
     list.addAll(Arrays.asList(tm.getAcceptedIssuers())); 
    } 

    return list.toArray(new X509Certificate[list.size()]); 
} 


} 

这是不优雅可言,但能够完成任务。

相关问题