web-dev-qa-db-ja.com

Android 4.4でTLS1.2を有効にする

リクエストにはRetrofitとOkHttp3を使用しています。 Android 4.4 TLS1.1とTLS1.2はデフォルトで有効にされていないので、有効にしようとしています。しかし、これまでのところ成功していません。 Androidスタジオエミュレーターの問題ですが、andoroid 4.4rigthnowを使用して実際のデバイスでテストを行うことはできません

これは私がこれまでに行ったことです:

_private <S> S createService(Class<S> serviceClass) {
    Retrofit retrofit = builder.client(getNewHttpClient()).build();
    return retrofit.create(serviceClass);
}

private OkHttpClient getNewHttpClient() {
    OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder()
            .connectTimeout(10, TimeUnit.SECONDS)
            .writeTimeout(10, TimeUnit.SECONDS)
            .readTimeout(0, TimeUnit.MINUTES); // Disable timeouts for read

    return enableTls12OnPreLollipop(clientBuilder).build();
}


public static OkHttpClient.Builder enableTls12OnPreLollipop(OkHttpClient.Builder client) {
    if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KitKat) {
        try {
            client.sslSocketFactory(new TLSSocketFactory());

            ConnectionSpec cs = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
                    .tlsVersions(TlsVersion.TLS_1_2)
                    .build();

            List<ConnectionSpec> specs = new ArrayList<>();
            specs.add(cs);
            specs.add(ConnectionSpec.COMPATIBLE_TLS);
            specs.add(ConnectionSpec.CLEARTEXT);

            client.connectionSpecs(specs);
        } catch (Exception exc) {
            Log.e("OkHttpClientProvider", "Error while enabling TLS 1.2", exc);
        }
    }

    return client;
}
_

TLSSocketFactory CLASS

_public class TLSSocketFactory extends SSLSocketFactory {
private SSLSocketFactory delegate;

public TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException {
    SSLContext context = SSLContext.getInstance("TLS");
    context.init(null, null, null);
    delegate = context.getSocketFactory();
}

@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 enableTLSOnSocket(delegate.createSocket(s, Host, port, autoClose));
}

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

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

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

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

private Socket enableTLSOnSocket(Socket socket) {
    if(socket != null && (socket instanceof SSLSocket)) {
        ((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"});
    }
    return socket;
}
}
_

this を試しましたが、機能しませんでした。

私のエラーは:javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0xb829bae0: Failure in SSL library, usually a protocol error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:741 0x8d9e3990:0x00000000)

7
Fabio Piunti

これを試してください: https://developer.Android.com/training/articles/security-gms-provider.html

https://developers.google.com/Android/reference/com/google/Android/gms/security/ProviderInstaller を使用しているため、プロジェクトにGoogleAPIが必要です。

アプリケーションを呼び出すだけです。

@Override
public void onCreate() {
    super.onCreate();
    try {
        ProviderInstaller.installIfNeeded(this);
    } catch (GooglePlayServicesRepairableException | GooglePlayServicesNotAvailableException e) {
        e.printStackTrace();
    }
}

カスタムSSLfactoryも削除する必要があります。

このエラーは通常、AndroidがTLSv1からSSLv3にフォールバックするときに発生します。これは、ロリポップ以前のデバイスのバグです。

解決策は、Androidのセキュリティプロバイダーを使用してSSLv3を削除することです。

このソリューションを試してください:

private void updateAndroidSecurityProvider(Activity callingActivity) {
    try {
        ProviderInstaller.installIfNeeded(this);
    } catch (GooglePlayServicesRepairableException e) {
    GooglePlayServicesUtil.getErrorDialog(e.getConnectionStatusCode(), callingActivity, 0);
    } catch (GooglePlayServicesNotAvailableException e) {
        Log.e("SecurityException", "Google Play Services not available.");
    }
}
3
Brian

Applicationクラスに追加します

@Override
public void onCreate() {
    super.onCreate();
    try {
            ProviderInstaller.installIfNeeded(this);
            SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
            sslContext.init(null, null, null);
            sslContext.createSSLEngine();
        } catch (GooglePlayServicesRepairableException | GooglePlayServicesNotAvailableException
                | NoSuchAlgorithmException | KeyManagementException e) {
            e.printStackTrace();
        }
}

重要-> Gradleで「com.squareup.okhttp3:okhttp:。*」ライブラリを使用しているかどうかを確認してください。使用しているバージョンが3.12.2であることを確認してください。以下。この問題がある3.12.2以降のバージョン

0