2

サーバーとAndroidクライアント間のTLS v1.2通信を作成しようとしています。問題なく TLS v1.0 接続を確立しましたが、v1.2 を取得できません。これはサーバーコードです:

char[] passphrase = "myComplexPass1".toCharArray();
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(new FileInputStream("cacerts"), passphrase);
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
keyManagerFactory.init(keystore, passphrase);
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
SSLContext sslContext.init(keyManagers, null, null);
SSLServerSocketFactory sslServerSocketFactory = sslContext.getServerSocketFactory();
SSLServerSocket sslServerSocket = (SSLServerSocket) sslServerSocketFactory.createServerSocket(port);
sslServerSocket.setEnabledProtocols(new String [] { "TLSv1", "TLSv1.1", "TLSv1.2" });
sslServerSocket.setUseClientMode(false);
sslServerSocket.setWantClientAuth(false);
sslServerSocket.setNeedClientAuth(false);
sslSocket = (SSLSocket)sslServerSocket.accept();

これはクライアントコードですが:

char[] passphrase = "myComplexPass1".toCharArray();
KeyStore keystore = KeyStore.getInstance("BKS");
keystore.load(this.getApplicationContext().getResources().openRawResource(R.raw.jb), passphrase);
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keystore, passphrase);
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
Log.d("Context Protocol",sslContext.getProtocol());//this prints correctly TLS v1.2!
KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
TrustManager[] trustManagers = new TrustManager[]{
                    new X509TrustManager() {
                        public java.security.cert.X509Certificate[] getAcceptedIssuers()
                        {
                            return null;
                        }
                        public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
                        {

                        }
                        public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)
                        {

                        }
                    }
            };
sslContext.init(keyManagers, trustManagers, new SecureRandom());
SSLSocketFactory sslSocketFactory = (SSLSocketFactory) sslContext.getSocketFactory();
SSLSocket skt = (SSLSocket) sslSocketFactory.createSocket(HOST, PORT);
skt.setKeepAlive(true);

私のPCのJRE7で実行されているJavaクライアントで記述されたクライアントコードは完全に機能し、tlsv1.2でサポートされている正しい暗号を使用したgetProtocol(サーバー側)TLSv1.2で確認できます。Android の同じコードで tlsv1.0 接続を確立します! 私は本当に理解していません。Java クライアントでは JRE7 が動作しますが、Android では tlsv1.0 のみで動作します。何か提案はありますか?

それは私の最初の質問です、私はたくさん検索しました。おそらく私のフォーマットは正しくありません:(

4

1 に答える 1

10

これに答えるのがちょっと遅いですが、他の誰かが答えを必要とするかもしれません。

私は同じ問題に遭遇しました。メソッドにTLSv1.2 を提供するかどうかにSSLContext.init()関係なく、私が試した一部の Android バージョンでは TLS 1.2 が有効になりません。setEnabledProtocols()サーバーソケットと同じように、クライアントソケットでそれを有効にする必要があります。私にとっては、私が作成したカスタムでこれを行いましたSSLSocketFactory

public class MySSLSocketFactory extends SSLSocketFactory
                                throws NoSuchAlgorithmException {

    private SSLContext mSSLContext;

    public MySSLSocketFactory(KeyManager km) {
        ...
        mSSLContext = SSLContext.getInstance("TLSv1.2");
        ...
        mSSLContext.init(new KeyManager[] {km}, null, null);
        ...
    }

    @Override
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
                    throws IOException {
        SSLSocket s = (SSLSocket)mSSLContext.getSocketFactory().createSocket(socket, host, port, autoClose);
        s.setEnabledProtocols(new String[] {"TLSv1.2"} );
        return s;
    }

    ...
}
于 2013-12-20T17:19:47.033 に答える