android - tls 在 android 中使用 session 票证

标签 android ssl

首先, 我想在android中使用session ticket,我的代码如下: String keyStoreType = KeyStore.getDefaultType(); KeyStore keyStore = KeyStore.getInstance(keyStoreType); keyStore.load(null, null);

    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抓取数据 block ,代码可以得到“ TLSv1.2 224 新 session 票证,更改密码规范,你好请求,你好请求” ,所以我想我得到了 session 票,但是当我重新连接到服务器时,客户端问候的“ session 票”内容如下: “扩展名: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);
    }
}

此代码甚至不启用 session ,tls 的版本始终是 TLSv1.0,谁能告诉我如何启用它并将 tls 的版本设置为 tlsv1.2? PS:我在android 4.4和L上测试过

最佳答案

Android 的 SSLCertificateSocketFactory 在某些/许多设备上已损坏。它不提供接口(interface)/方法供您指定启用的协议(protocol)。相反,它只是使用 enabledProtocols 的系统默认值。在早期的 Android 设备上,这将是 TLS 和 SSL3,而不是 TLSv1.2。

由于它的实现方式,您不能将它子类化并试图覆盖它的行为。您无法设置所需的 TLS 协议(protocol),更不用说设置您可能需要控制的密码组了。

不幸的是,SSLCertificateSocketFactory 的一些其他功能也丢失了。例如,如果没有它,您将无法启用 SNI 或“正式”设置 alpns 协议(protocol)。

因此,您的解决方案需要子类化 SSLSocketFactory 以提供您自己的套接字工厂来控制您在第一个代码示例中所做的所需设置。您可以使用上面的反射技巧在您自己的 createSocket() 方法实现中启用 session 票证。

关于android - tls 在 android 中使用 session 票证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31023531/

相关文章:

security - 数字证书在用于保护网站(使用 SSL)时如何工作?

MySQL - SSL - 使用 TLS1.2 密码 AES256-SHA256/DHE-RSA-AES256-SHA256

internet-explorer - IE 在 iframe 页面 (SSL) 上悄悄地丢弃 cookies?

android退出全屏模式

android - 新的 Android 12+ MaterialSwitch 和 androidx.preference

java - 屏幕旋转后的 fragment Activity 引用

macos - 如何在 Mac OS 10.7 Lion 上嗅探数据包?

ssl - 如何获取 'Chrome has detected insecure content' 而不是 'Chrome has detected either high-risk insecure content'

Java_Home 使用 ionic

java - 什么?android :attr/listPreferredItemHeight is doing and how?