Android应用中使用JSch禁用TLSv1.0的可行方案咨询
Android 禁用TLSv1.0的可行方案(针对JSch场景)
你之前尝试的两种方法无效的原因:
System.setProperty("https.protocols", "TLSv1.2"):仅对系统HttpsURLConnection生效,JSch这类自定义网络实现不会读取该属性。- 修改默认
SSLContext的参数:JSch通常会创建独立的SSLContext实例,不会复用系统默认的,所以配置无法生效。
针对你的JSch SSH端口转发场景,推荐以下两种解决方案:
方案一:给JSch配置自定义SSLContext
直接为JSch指定仅支持TLSv1.2的SocketFactory,从根源上限制协议版本:
import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.SocketFactory; import javax.net.ssl.SSLContext; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; // 创建仅支持TLSv1.2的SSLContext SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); sslContext.init(null, null, null); javax.net.ssl.SocketFactory systemSocketFactory = sslContext.getSocketFactory(); // 适配JSch的SocketFactory接口 SocketFactory jschSocketFactory = new SocketFactory() { @Override public Socket createSocket(String host, int port) throws IOException, UnknownHostException { return systemSocketFactory.createSocket(host, port); } @Override public InputStream getInputStream(Socket socket) throws IOException { return socket.getInputStream(); } @Override public OutputStream getOutputStream(Socket socket) throws IOException { return socket.getOutputStream(); } }; // 配置JSch会话使用自定义SocketFactory JSch jsch = new JSch(); Session session = jsch.getSession("username", "host", 22); session.setConfig("socket_factory", jschSocketFactory); // 后续完成会话的其他配置(如密钥、密码)并连接
方案二:全局限制Android系统网络请求的TLS版本
如果需要对整个应用的系统网络请求(如HttpsURLConnection)禁用TLSv1.0,可以通过自定义SSLSocketFactory实现:
1. 自定义SSLSocketFactory
import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import java.io.IOException; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; public class TLS12OnlySocketFactory extends SSLSocketFactory { private final SSLSocketFactory delegate; public TLS12OnlySocketFactory() { this.delegate = HttpsURLConnection.getDefaultSSLSocketFactory(); } @Override public String[] getDefaultCipherSuites() { return delegate.getDefaultCipherSuites(); } @Override public String[] getSupportedCipherSuites() { return delegate.getSupportedCipherSuites(); } private Socket enforceTLS12(Socket socket) { if (socket instanceof SSLSocket) { ((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1.2"}); } return socket; } @Override public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException { return enforceTLS12(delegate.createSocket(s, host, port, autoClose)); } @Override public Socket createSocket(String host, int port) throws IOException, UnknownHostException { return enforceTLS12(delegate.createSocket(host, port)); } @Override public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException { return enforceTLS12(delegate.createSocket(host, port, localHost, localPort)); } @Override public Socket createSocket(InetAddress host, int port) throws IOException { return enforceTLS12(delegate.createSocket(host, port)); } @Override public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException { return enforceTLS12(delegate.createSocket(address, port, localAddress, localPort)); } }
2. 全局配置生效
在应用启动时(如Application的onCreate方法)设置:
import java.security.Security; Security.setProperty("ssl.SocketFactory.provider", "com.yourpackage.TLS12OnlySocketFactory");
注意:Android 7.0及以上系统默认已禁用TLSv1.0和TLSv1.1,该方案主要针对Android 6.0及以下版本。
内容的提问来源于stack exchange,提问作者raitech
相关产品推荐
相关产品推荐

