web-dev-qa-db-ja.com

SSLEngineでTLSv1.2を使用するAndroid(4.4.2)?

皆さん、私が行方不明になっていることが明らかであることを願っています。誰かが光を当てられることを願っています。 (+ AndroidAsync ライブラリを使用して)SSL + NIOコンテキストでTLSv1.2を実行しようとしているので、SSLEngine経由で有効にしようとしています。次のようなコードを実行できます。

_        SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
        sslContext.init(null, null, null);
        String[] protocols = sslContext.getSupportedSSLParameters().getProtocols();
        for (String protocol : protocols) {
            Timber.d("Context supported protocol: " + protocol);
        }

        SSLEngine engine = sslContext.createSSLEngine();
        String[] supportedProtocols = engine.getSupportedProtocols();
        for (String protocol : supportedProtocols) {
            Timber.d("Engine supported protocol: " + protocol);
        }
_

そして、私はlogcatでこれを見ます:

_06-22 21:56:27.715    1117-1117/? D/XXX﹕ Context supported protocol: SSLv3
06-22 21:56:27.715    1117-1117/? D/XXX﹕ Context supported protocol: TLSv1
06-22 21:56:27.725    1117-1117/? D/XXX﹕ Context supported protocol: TLSv1.1
06-22 21:56:27.725    1117-1117/? D/XXX﹕ Context supported protocol: TLSv1.2
06-22 21:56:27.735    1117-1117/? D/XXX﹕ Engine supported protocol: TLSv1
06-22 21:56:27.745    1117-1117/? D/XXX﹕ Engine supported protocol: SSLv3
_

もちろん、engine.setEnabledProtocols(new String[] { "TLSv1.2" })を実行しようとすると、「プロトコルTLSv1.2はサポートされていません」というIllegalArgumentExceptionが表示されます。

TLSv1.2をサポートするというコンテキストクレームを見ることができますが、そのコンテキストから作成するエンジンはそうではありませんか?何が起きてる?上記の最初の行で「TLSv1.2」の代わりに「TLS」を使用しても、これは変わりません。

これは this issue と関係があるかもしれませんが、 this(まだ回答されていない)質問this like article を読んでいますしかし、彼らはスポットに当たっていないようです-私が見たソリューションはすべてSSLEngineではなくSSLSocketに依存しているようです。

落とすことができる知識をありがとう。

UPDATE 6/23/14 10AMEDT

そこで_SSLEngine.setSSLParameters_を見つけました。SSLContext.getSupportedSSLParameters()から取得したSSLParametersを渡すことを望んでいましたが、それを呼び出すと暗号スイートがサポートされていないという例外が発生します、したがって、setSSLParameters()はsetEnabledCipherSuites()と同じことを行っているように見え、エンジンは既にTLS 1.2プロトコル/スイートがサポートされていると認識していない状態にあります。

21
Glen

Android API docs 正しく) TLSv1.2はAPIレベル20以降(Lollipop)のSSLEngineでのみサポートされ、SSLSocketはレベル16以降でサポートします。

SSLSocketを使用したり、API 20を要求したりすることはプロジェクトの選択肢ではなく、TLSv1またはSSLv3を許可するようにサーバーコードを変更することもありませんでした。私たちのソリューションは、 Google Play Services を使用して新しいセキュリティプロバイダーをインストールすることでした:

    ProviderInstaller.installIfNeeded(getApplicationContext());

これにより、アプリはOpenSSLの新しいバージョンとSSLEngineでTLSv1.2のサポートを含むJavaセキュリティプロバイダーにアクセスできます。新しいプロバイダーをインストールしたら、SSLv3をサポートするSSLEngineを作成できます、TLSv1、TLSv1.1およびTLSv1.2の通常の方法:

    SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
    sslContext.init(null, null, null);
    SSLEngine engine = sslContext.createSSLEngine();

または、engine.setEnabledProtocolsを使用して、有効なプロトコルを制限できます。

62
Wolfgang Profer

OkHttpを使用している場合は、このソリューションを試してください。 Android 4.4 でTLSv1.2を有効にするためのソリューション

Android <5.0(16 <= API <20)に同じ問題がありました。あなたの投稿のおかげで、私はこの作品を作ることができました。すぐに使えるソリューションこの執筆時点では、OkHttp 3.4.1を使用しています。

タグ:受け入れ可能なプロトコルが見つかりません、javax.net.ssl.SSLProtocolException:SSLハンドシェイクが中止されました:

4
AAnkit

AndroidAsyncの使用方法は次のとおりです。

ProviderInstaller.installIfNeeded(context);
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(KeyManager[] km, TrustManager[] tm, SecureRandom rm);
SSLEngine engine = sslContext.createSSLEngine();
AsyncHttpClient.getDefaultInstance().insertMiddleware((AsyncHttpClientMiddleware) engine); 

SSLEngineを更新し、ミドルウェアとしてAndroidAsyncに挿入すると動作するようです。

3
Jordan Réjaud