2013-05-13 81 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