当前位置: 首页 > 知识库问答 >
问题:

如何在Android应用程序(在Android 4.1 JB上运行)中启用TLS 1.2支持

伯俊弼
2023-03-14

根据Android中关于SSLSocketSSLContext的文档,TLS v1。1和v1。API级别16支持2个协议,但默认情况下不启用。http://developer.android.com/reference/javax/net/ssl/SSLSocket.html http://developer.android.com/reference/javax/net/ssl/SSLContext.html

如何在运行Android 4.1或更高版本(但低于5.0)的设备上启用它?

我曾尝试创建一个自定义SSLSocketFactory,在创建套接字时启用所有受支持的协议,然后将我的自定义实现用作:

HttpsURLConnection.setDefaultSSLSocketFactory(新的MySSLSocketFactory());

public class MySSLSocketFactory extends SSLSocketFactory {
        
        private SSLContext sc;
        private SSLSocketFactory ssf;  
        
        public MySSLSocketFactory() {
            try {
                sc = SSLContext.getInstance("TLS");
                sc.init(null, null, null);
                ssf = sc.getSocketFactory();

            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (KeyManagementException e) {
                e.printStackTrace();
            }  
        }
        
        @Override
        public Socket createSocket(Socket s, String host, int port, boolean autoClose)
                throws IOException {
            SSLSocket ss = (SSLSocket) ssf.createSocket(s, host, port, autoClose);
            ss.setEnabledProtocols(ss.getSupportedProtocols());
            ss.setEnabledCipherSuites(ss.getSupportedCipherSuites());
            return ss;
        }

        @Override
        public String[] getDefaultCipherSuites() {
            return ssf.getDefaultCipherSuites();
        }

        @Override
        public String[] getSupportedCipherSuites() {
            return ssf.getSupportedCipherSuites();
        }

        @Override
        public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
            SSLSocket ss = (SSLSocket) ssf.createSocket(host, port);
            ss.setEnabledProtocols(ss.getSupportedProtocols());
            ss.setEnabledCipherSuites(ss.getSupportedCipherSuites());
            return ss;
        }

        @Override
        public Socket createSocket(InetAddress host, int port) throws IOException {
            SSLSocket ss = (SSLSocket) ssf.createSocket(host, port);
            ss.setEnabledProtocols(ss.getSupportedProtocols());
            ss.setEnabledCipherSuites(ss.getSupportedCipherSuites());
            return ss;
        }

        @Override
        public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
                throws IOException, UnknownHostException {
            SSLSocket ss = (SSLSocket) ssf.createSocket(host, port, localHost, localPort);
            ss.setEnabledProtocols(ss.getSupportedProtocols());
            ss.setEnabledCipherSuites(ss.getSupportedCipherSuites());
            return ss;
        }

        @Override
        public Socket createSocket(InetAddress address, int port, InetAddress localAddress,
                int localPort) throws IOException {
            SSLSocket ss = (SSLSocket) ssf.createSocket(address, port, localAddress, localPort);
            ss.setEnabledProtocols(ss.getSupportedProtocols());
            ss.setEnabledCipherSuites(ss.getSupportedCipherSuites());
            return ss;
        }
    }

但是,当试图与仅启用TLS 1.2的服务器建立连接时,它仍然会给出异常。

以下是我得到的一个例外:

03-09:21:38.427:W/系统。err(2496):javax。网ssl。SSLHandshakeException:javax。网ssl。SSLProtocolException:SSL握手中止:SSL=0xb7fa0620:SSL库中出现故障,通常是协议错误

03-09:21:38.427:W/系统。err(2496):错误:14077410:SSL例程:SSL23_GET_SERVER_HELLO:sslv3警报握手失败(外部/openssl/SSL/s23_clnt.c:741 0xa90e6990:0x00000000)


共有3个答案

司马昕
2023-03-14

在Androidbuild中添加play services safetynetlibrary。格雷德尔

implementation 'com.google.android.gms:play-services-safetynet:+'

并将此代码添加到您的MainApplication.java

@Override
  public void onCreate() {
    super.onCreate();
    upgradeSecurityProvider();
    SoLoader.init(this, /* native exopackage */ false);
  }

  private void upgradeSecurityProvider() {
    ProviderInstaller.installIfNeededAsync(this, new ProviderInstallListener() {
      @Override
      public void onProviderInstalled() {

      }

      @Override
      public void onProviderInstallFailed(int errorCode, Intent recoveryIntent) {
//        GooglePlayServicesUtil.showErrorNotification(errorCode, MainApplication.this);
        GoogleApiAvailability.getInstance().showErrorNotification(MainApplication.this, errorCode);
      }
    });
  }
陶朝明
2023-03-14

我按照文章中提供的指示解决了这个问题http://blog.dev-area.net/2015/08/13/android-4-1-enable-tls-1-1-and-tls-1-2/没什么变化。

SSLContext context = SSLContext.getInstance("TLS");
context.init(null, null, null);
SSLSocketFactory noSSLv3Factory = null;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
    noSSLv3Factory = new TLSSocketFactory(sslContext.getSocketFactory());
} else {
    noSSLv3Factory = sslContext.getSocketFactory();
}
connection.setSSLSocketFactory(noSSLv3Factory);

这是定制TLSSocketFactory的代码:

public static class TLSSocketFactory extends SSLSocketFactory {

    private SSLSocketFactory internalSSLSocketFactory;

    public TLSSocketFactory(SSLSocketFactory delegate) throws KeyManagementException, NoSuchAlgorithmException {
        internalSSLSocketFactory = delegate;
    }

    @Override
    public String[] getDefaultCipherSuites() {
        return internalSSLSocketFactory.getDefaultCipherSuites();
    }

    @Override
    public String[] getSupportedCipherSuites() {
        return internalSSLSocketFactory.getSupportedCipherSuites();
    }

    @Override
    public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose));
    }

    @Override
    public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
    }

    @Override
    public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort));
    }

    @Override
    public Socket createSocket(InetAddress host, int port) throws IOException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
    }

    @Override
    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort));
    }

    /*
     * Utility methods
     */

    private static Socket enableTLSOnSocket(Socket socket) {
        if (socket != null && (socket instanceof SSLSocket)
                && isTLSServerEnabled((SSLSocket) socket)) { // skip the fix if server doesn't provide there TLS version
            ((SSLSocket) socket).setEnabledProtocols(new String[]{TLS_v1_1, TLS_v1_2});
        }
        return socket;
    }

    private static boolean isTLSServerEnabled(SSLSocket sslSocket) {
        System.out.println("__prova__ :: " + sslSocket.getSupportedProtocols().toString());
        for (String protocol : sslSocket.getSupportedProtocols()) {
            if (protocol.equals(TLS_v1_1) || protocol.equals(TLS_v1_2)) {
                return true;
            }
        }
        return false;
    }
}

编辑:感谢ademar111190实现kotlin(链接)

class TLSSocketFactory constructor(
        private val internalSSLSocketFactory: SSLSocketFactory
) : SSLSocketFactory() {

    private val protocols = arrayOf("TLSv1.2", "TLSv1.1")

    override fun getDefaultCipherSuites(): Array<String> = internalSSLSocketFactory.defaultCipherSuites

    override fun getSupportedCipherSuites(): Array<String> = internalSSLSocketFactory.supportedCipherSuites

    override fun createSocket(s: Socket, host: String, port: Int, autoClose: Boolean) =
            enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose))

    override fun createSocket(host: String, port: Int) =
            enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port))

    override fun createSocket(host: String, port: Int, localHost: InetAddress, localPort: Int) =
            enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort))

    override fun createSocket(host: InetAddress, port: Int) =
            enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port))

    override fun createSocket(address: InetAddress, port: Int, localAddress: InetAddress, localPort: Int) =
            enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort))

    private fun enableTLSOnSocket(socket: Socket?) = socket?.apply {
        if (this is SSLSocket && isTLSServerEnabled(this)) {
            enabledProtocols = protocols
        }
    }

    private fun isTLSServerEnabled(sslSocket: SSLSocket) = sslSocket.supportedProtocols.any { it in protocols }

}
越信鸥
2023-03-14

2种启用TLSv1的方法。1和TLSv1。2:

  1. 使用本指南:http://blog.dev-area.net/2015/08/13/android-4-1-enable-tls-1-1-and-tls-1-2/
  2. 使用这个类https://github.com/erickok/transdroid/blob/master/app/src/main/java/org/transdroid/daemon/util/TlsSniSocketFactory.java
    schemeRegistry.register(新方案("https", new TlsSniSocketFactory(), port));
 类似资料:
  • 问题内容: 我是一名Android开发人员,我想在我的应用程序中编写一条语句。在此语句中,我要检查默认浏览器(Android OS中 问题答案: 添加下面的Helper类: 现在,你可以从以下代码中检查所需的应用程序是否正在运行:

  • 我正在Android应用程序中创建一个项目。我已经在java eclipse环境中将java jdt ast作为独立应用程序实现了,并且我在控制台输出上得到了我需要的东西。现在我想把这个代码运行到我的Android应用程序项目中。但是,当我在文本中设置所有输出时,当我启动应用程序时,Android的视图,不幸的是它停止了,我不知道为什么...有人会知道为什么会发生这种情况吗?感谢您的帮助。 代码没

  • 问题内容: 我正在用Java开发使用Lua脚本的Android游戏。为了执行这些脚本,我将LuaJ与Java的ScriptEngine类一起使用。例如… 但是,Android显然不支持此功能(这与android没有完整的JVM有关,我在某处读过)。有什么方法可以在Android上使用Lua脚本吗?也许有一个LuaJ替代方案?也许有一种直接使用LuaJ编译和执行Lua脚本的方法(尽管我看不到如何)。

  • 我需要在具有自签名证书的Spring Boot 2.0.5应用程序上启用HTTPS,然而,到目前为止,我在配置中发现的所有内容都与设置一个名为的属性有关,但在这个Spring Boot版本上,该属性似乎不推荐使用...在Spring Boot应用程序上启用HTTPS还有其他方法吗?

  • 问题内容: 我创建了新的libgdx项目,并且想在Android Studio中运行桌面应用程序。与运行配置有关吗?在Eclipse中,我可以选择“以Java应用程序运行”。 问题答案: 好吧,我做到了。这是解决方案https://github.com/libgdx/libgdx/wiki/Gradle-and-Intellij- IDEA#running-your-project ,单击加号()

  • 我用JDK 13制作了一个java应用程序。我用launch4j创建了一个exe文件。但是没有人可以运行它,因为每个人都有jre 1.8版本,而且它不会启动。。。我必须在安装中包含java jdk 13,并用它设置java_home?