2015-06-24 69 views
0

首先, 我想在android中使用會話票據,我的代碼如下: String keyStoreType = KeyStore.getDefaultType(); KeyStore keyStore = KeyStore.getInstance(keyStoreType); keyStore.load(null,null);tls在android中使用會話票據

String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); 
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); 
    tmf.init(keyStore); 

    SSLContext cpmContext = SSLContext.getInstance("TLSv1.2"); 
    cpmContext.init(null, null, null); 
    SSLSocket socket = (SSLSocket) cpmContext.getSocketFactory().createSocket(ip, port); 
    socket.setEnabledProtocols(socket.getEnabledProtocols()); 
    socket.setEnabledCipherSuites(socket.getEnabledCipherSuites()); 
    Class c = socket.getClass(); 
    try { 
     Method m = c.getMethod("setUseSessionTickets",boolean.class); 
     m.invoke(socket,true); 
    } catch (NoSuchMethodException e) { 
     e.printStackTrace(); 
    } catch (IllegalAccessException e) { 
     e.printStackTrace(); 
    } catch (IllegalArgumentException e) { 
     e.printStackTrace(); 
    } catch (InvocationTargetException e) { 
     e.printStackTrace(); 
    } 
    SSLSession session = socket.getSession(); 

我捕捉tcpdump的數據塊,旋轉,代碼可以得到「 TLSv1.2工作224新會話票據,變更密碼說明,問候請求,問候請求」 ,所以我覺得我得到的會話票證,但是當我重新連接到服務器,「會話票據」客戶端問候的內容如下: ‘擴展:sessionTicket TLS 類型:sessionTicket TLS(0x0023) 長度:0 數據:(0字節)’ 它沒有執行恢復。

然後我用SSLCertificateSocketFactory創建的SSLSocket:

private Socket createSocketOnLine(final String ip, final int port) throws UnknownHostException, IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException, KeyManagementException { 
    SSLCertificateSocketFactory sf = (SSLCertificateSocketFactory) SSLCertificateSocketFactory 
      .getDefault(30 * 1000); 
    SSLSocket socket = (SSLSocket) sf.createSocket(ip, port); 
    socket.setEnabledProtocols(socket.getEnabledProtocols()); 
    socket.setEnabledCipherSuites(socket.getEnabledCipherSuites()); 
    enableSessionTicket(sf, socket); 
    SSLSession session = socket.getSession(); 
    return socket; 
} 

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) 
public void enableSessionTicket(SSLCertificateSocketFactory sf, Socket socket) { 
    if (VERSION.SDK_INT > 17) { 
     sf.setUseSessionTickets(socket, true); 
    } 
} 

這個代碼DONOT甚至啓用TLS的會話和版本的TLS總是TLSv1.0,誰可以告訴我如何啓用並設置版本是tlsv1.2? PS:我測試它在Android 4.4和L

回答

0

Android的SSLCertificateSocketFactory在某些/許多設備上被打破。它不提供用於指定已啓用協議的接口/方法。相反,它只是使用enabledProtocols的系統默認值。在早期的Android設備上,這將是TLS和SSL3,而不是TLSv1.2。

由於它的實現方式,你不能繼承它並試圖覆蓋它的行爲。您無法設置所需的TLS協議,更不用說設置您可能需要控制的密碼組。

不幸的是,SSLCertificateSocketFactory的一些其他功能也丟失了。例如,如果沒有它,您將無法啓用SNI或「正式」設置alpns協議。

因此,您的解決方案需要繼承SSLSocketFactory的子類以提供您自己的socketfactory來控制您在第一個代碼示例中所需的設置。您可以使用上面的反射技巧在自己的createSocket()方法實現中啓用會話票據。