当服务器上禁用TLS1.0和1.1时,即使是最新版本的Android应用程序也会崩溃
我最近在服务器端禁用了对TLS1.0和1.1的支持,所有Android应用程序都停止工作。我知道Android 4及以下版本不支持TSL1.2或更高版本,但即使是运行在Android 10上的应用程序也停止工作。手机上的堆栈跟踪显示TLS问题。iPhone上安装的应用程序看不到任何问题。当我们启用对TLS 1.0和1.1 Android应用程序的支持时,所有Android手机都可以正常工作,但随后服务器的安全审计就会停止。安卓操作系统中是否有支持TLS 1.2的功能?我最近也遇到了同样的问题,在互联网紧缩中读到了这一点。在您当前的系统中,可能有多个地方,即使是在最新的安卓版本上,呼叫也会失败。但是,您可以执行两个主要步骤来确保您的应用程序已为TLS 1.2做好准备:当服务器上禁用TLS1.0和1.1时,即使是最新版本的Android应用程序也会崩溃,android,tls1.2,Android,Tls1.2,我最近在服务器端禁用了对TLS1.0和1.1的支持,所有Android应用程序都停止工作。我知道Android 4及以下版本不支持TSL1.2或更高版本,但即使是运行在Android 10上的应用程序也停止工作。手机上的堆栈跟踪显示TLS问题。iPhone上安装的应用程序看不到任何问题。当我们启用对TLS 1.0和1.1 Android应用程序的支持时,所有Android手机都可以正常工作,但随后服务器的安全审计就会停止。安卓操作系统中是否有支持TLS 1.2的功能?我最近也遇到了同样的问题,在
com.Google.android.gms.security.ProviderInstaller
)。在创建任何HttpClient资源之前,您必须在代码中执行此操作(否则它们将使用较旧的安全规范),在您的主要活动的onCreate
中执行类似操作应该可以很好地工作:
try {
ProviderInstaller.installIfNeeded(this);
Log.i(LOG_TAG, "Google Play Services Installed");
} catch (GooglePlayServicesRepairableException e) {
GoogleApiAvailability.getInstance()
.showErrorNotification(this, e.getConnectionStatusCode());
Log.i(LOG_TAG, "Error", e);
} catch (GooglePlayServicesNotAvailableException e) {
Log.i(LOG_TAG, "Error", e);
}
在创建任何http客户机之前运行此命令非常重要,否则它们将不支持TLS 1.2导入android.os.Build;
导入android.util.Log;
导入java.io.IOException;
导入java.net.InetAddress;
导入java.net.Socket;
导入java.net.UnknownHostException;
导入java.util.ArrayList;
导入java.util.List;
导入java.util.concurrent.TimeUnit;
导入javax.net.ssl.SSLContext;
导入javax.net.ssl.SSLEngine;
导入javax.net.ssl.SSLSocket;
导入javax.net.ssl.SSLSocketFactory;
导入okhttp3.CipherSuite;
导入okhttp3.ConnectionSpec;
导入okhttp3.OkHttpClient;
导入okhttp3.TlsVersion;
/**
*创建SSLSockets时启用TLS v1.2。
*
*出于某种原因,android支持API 16中的TLS v1.2,但通过
*默认值仅来自API 20。
*@linkhttps://developer.android.com/reference/javax/net/ssl/SSLSocket.html
*@见SSLSocketFactory
*/
公共类Tls12SocketFactory扩展了SSLSocketFactory{
私有静态最终字符串[]TLS_V12_ONLY={“TLSv1.2”};
最终SSLSocketFactory代表;
公共Tls12SocketFactory(SSLSocketFactory基地){
this.delegate=base;
}
@凌驾
公共字符串[]GetDefaultCipherSuite(){
返回delegate.getDefaultCipherSuite();
}
@凌驾
公共字符串[]GetSupportedCipherSuite(){
返回delegate.getSupportedCipherSuite();
}
@凌驾
公共套接字createSocket(套接字、字符串主机、int端口、布尔自动关闭)引发IOException{
返回补丁(delegate.createSocket(s、主机、端口、自动关闭));
}
@凌驾
公共套接字createSocket(字符串主机,int端口)引发IOException,UnknownHostException{
返回补丁(delegate.createSocket(主机、端口));
}
@凌驾
公共套接字createSocket(字符串主机、int端口、InetAddress本地主机、int本地端口)引发IOException、UnknownHostException{
返回补丁(delegate.createSocket(主机、端口、本地主机、本地端口));
}
@凌驾
公共套接字createSocket(InetAddress主机,int端口)引发IOException{
返回补丁(delegate.createSocket(主机、端口));
}
@凌驾
公共套接字createSocket(InetAddress地址、int端口、InetAddress本地地址、int本地端口)引发IOException{
返回补丁(delegate.createSocket(地址、端口、本地地址、本地端口));
}
专用套接字修补程序(套接字s){
如果(SSLSocket的实例){
((SSLSocket)s).可设置的协议(仅限TLS_V12_);
}
返回s;
}
私有静态最终密码套件[]批准的密码套件=新密码套件[]{
//TLSv1.3
CipherSuite.TLS_AES_128_GCM_SHA256,
CipherSuite.TLS_AES_256_GCM_SHA384,
CipherSuite.TLS_CHACHA20_poly 1305_SHA256,
CipherSuite.TLS_AES_128_CCM_SHA256,
CipherSuite.TLS_AES_256_CCM_8_SHA256,
CipherSuite.TLS_ECDHE_ECDSA_与_AES_128_GCM_SHA256,
CipherSuite.TLS_ECDHE_RSA_与_AES_128_GCM_SHA256,
CipherSuite.TLS_ECDHE_ECDSA_与_AES_256_GCM_SHA384,
CipherSuite.TLS_ECDHE_RSA_与_AES_256_GCM_SHA384,
CipherSuite.TLS_ECDHE_ECDSA_与_CHACHA20_poly 1305_SHA256,
CipherSuite.TLS_ECDHE_RSA_与_CHACHA20_poly 1305_SHA256,
//请注意,以下密码套件都在HTTP/2的坏密码套件列表中
//继续包括它们,直到更好的套件普遍可用。例如,没有
//上面列出的更好的密码套件中有一个是随Android 4.4或Java 7提供的。
CipherSuite.TLS_ECDHE_RSA_与_AES_128_CBC_SHA,
CipherSuite.TLS_ECDHE_RSA_与_AES_256_CBC_SHA,
CipherSuite.TLS\u RSA\u和\u AES\u 128\u GCM\u SHA256,
CipherSuite.TLS\u RSA\u和\u AES\u 256\u GCM\u SHA384,
CipherSuite.TLS_RSA_与_AES_128_CBC_SHA,
CipherSuite.TLS\u RSA\u和\u AES\u 256\u CBC\u SHA,
CipherSuite.TLS\u RSA\u和\u 3DES\u EDE\u CBC\u SHA,
};
公共静态OkHttpClient.Builder启用TLS12ONPLELOLLIPOP(OkHttpClient.Builder客户端){
如果(Build.VERSION.SDK_INT<22){
试一试{
SSLContext sc=SSLContext.getInstance(“TLSv1.2”);
sc.init(null,null,null);
client.sslSocketFactory(新的Tls12SocketFactory(sc.getSocketFactory());
ConnectionSpec cs=新的ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.密码套件
import android.os.Build;
import android.util.Log;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import okhttp3.CipherSuite;
import okhttp3.ConnectionSpec;
import okhttp3.OkHttpClient;
import okhttp3.TlsVersion;
/**
* Enables TLS v1.2 when creating SSLSockets.
* <p/>
* For some reason, android supports TLS v1.2 from API 16, but enables it by
* default only from API 20.
* @link https://developer.android.com/reference/javax/net/ssl/SSLSocket.html
* @see SSLSocketFactory
*/
public class Tls12SocketFactory extends SSLSocketFactory {
private static final String[] TLS_V12_ONLY = {"TLSv1.2"};
final SSLSocketFactory delegate;
public Tls12SocketFactory(SSLSocketFactory base) {
this.delegate = base;
}
@Override
public String[] getDefaultCipherSuites() {
return delegate.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return delegate.getSupportedCipherSuites();
}
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
return patch(delegate.createSocket(s, host, port, autoClose));
}
@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return patch(delegate.createSocket(host, port));
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
return patch(delegate.createSocket(host, port, localHost, localPort));
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return patch(delegate.createSocket(host, port));
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return patch(delegate.createSocket(address, port, localAddress, localPort));
}
private Socket patch(Socket s) {
if (s instanceof SSLSocket) {
((SSLSocket) s).setEnabledProtocols(TLS_V12_ONLY);
}
return s;
}
private static final CipherSuite[] APPROVED_CIPHER_SUITES = new CipherSuite[] {
// TLSv1.3
CipherSuite.TLS_AES_128_GCM_SHA256,
CipherSuite.TLS_AES_256_GCM_SHA384,
CipherSuite.TLS_CHACHA20_POLY1305_SHA256,
CipherSuite.TLS_AES_128_CCM_SHA256,
CipherSuite.TLS_AES_256_CCM_8_SHA256,
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
// Note that the following cipher suites are all on HTTP/2's bad cipher suites list. We'll
// continue to include them until better suites are commonly available. For example, none
// of the better cipher suites listed above shipped with Android 4.4 or Java 7.
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384,
CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA,
CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA,
CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
};
public static OkHttpClient.Builder enableTls12OnPreLollipop(OkHttpClient.Builder client) {
if (Build.VERSION.SDK_INT < 22) {
try {
SSLContext sc = SSLContext.getInstance("TLSv1.2");
sc.init(null, null, null);
client.sslSocketFactory(new Tls12SocketFactory(sc.getSocketFactory()));
ConnectionSpec cs = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.cipherSuites(APPROVED_CIPHER_SUITES)
.tlsVersions(TlsVersion.TLS_1_3, TlsVersion.TLS_1_2)
.supportsTlsExtensions(true)
.build();
List<ConnectionSpec> specs = new ArrayList<>();
specs.add(cs);
client.connectionSpecs(specs);
Log.i("OkHttpTLSCompat", "TLS 1.2 enabled");
} catch (Exception exc) {
Log.e("OkHttpTLSCompat", "Error while setting TLS 1.2", exc);
}
}
return client;
}
public static OkHttpClient returnClient() {
OkHttpClient.Builder client = new OkHttpClient.Builder()
.followRedirects(true)
.followSslRedirects(true)
.retryOnConnectionFailure(true)
.cache(null)
.connectTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS);
return enableTls12OnPreLollipop(client).build();
}
}