2015-06-24 33 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()方法实现中启用会话票据。