2013-05-13 82 views
2

我正在嘗試在服務器和Android客戶端之間創建TLS v1.2通信。 我與任何問題建立了TLS v1.0連接,但我無法獲得v1.2。 這是服務器代碼:TLS v1.2上的Android客戶端/服務器

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); 

客戶端代碼,寫在我的電腦上JRE7運行的Java客戶端,完美的作品和我的getProtocol(服務器見端)帶有正確密碼的TLSv1.2,由tlsv1.2支持。 在android上的相同的代碼使tlsv1.0連接! 我真的不明白。 在Java客戶端JRE7上工作,在android ONLY tlsv1.0 任何建議?

這是我的第一個問題,我搜查了很多。也許我的格式不正確:(

+0

TLS 1.2在Android 4.1上可用。請參閱http://stackoverflow.com/questions/5950178/執行tls-1-2-on-android-2-3-3瞭解更多詳情。 – 2013-05-14 06:03:20

+0

謝謝,但根據此[鏈接](http://source.android.com/tech/security/android_4_2_security_enhancements.html)它應該被支持。我正在運行android 4.2.2 – 2013-05-14 07:04:00

回答

9

後期要回答這個問題,但也許其他人會需要一個答案類。

我遇到了同樣的問題。無論你是否提供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; 
    } 

    ... 
} 
+0

如果你能讓我知道這是否適用於從2.3版本到JellyBean的Android版本,那該多好? – 2015-07-05 09:25:03

+0

從https://developer.android.com/reference/javax/net/ssl/SSLSocket.html,只有API版本16+支持TLS 1.2。 – cren90 2015-10-06 22:05:05

+0

這節省了我的一天。 Android有時會這樣做,這很奇怪,但是非常感謝。 – hmartinezd 2015-10-15 00:38:25