java TLS v1.2 上的 Android 客户端/服务器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16531807/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android Client / Server on TLS v1.2
提问by Guido Davide
I'm trying my to create TLS v1.2 communication between a server and android client. I established a TLS v1.0 connection with any problem, but I cannot get v1.2. This is server code:
我正在尝试在服务器和 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();
while this is client code:
虽然这是客户端代码:
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);
Client code, written in a java client running on JRE7 on my pc, perfectly works and I see with getProtocol (server-side) TLSv1.2 with a correct cipher, supported by tlsv1.2. Same code on android make a tlsv1.0 connection! I really don't uderstand. On Java client JRE7 works, on android ONLY tlsv1.0 Any suggestion?
客户端代码是在我的电脑上运行在 JRE7 上的 Java 客户端中编写的,完美运行,我看到 getProtocol(服务器端)TLSv1.2 具有正确的密码,由 tlsv1.2 支持。android 上的相同代码建立 tlsv1.0 连接!我真的不明白。在 Java 客户端 JRE7 上工作,仅在 android 上 tlsv1.0 有什么建议吗?
It's my first question, I searched a lot. Probably my formatting is not correct :(
这是我的第一个问题,我搜索了很多。可能我的格式不正确:(
回答by BJV
Kind of late to be answering this, but maybe someone else will need an answer.
回答这个问题有点晚了,但也许其他人需要答案。
I have run into the same issue. No matter whether you provide TLSv1.2 to the SSLContext.init()
method, some Android versions that I've tried do not enable TLS 1.2. You must enable that on your client socket using setEnabledProtocols()
just as you do for your server socket. For me, I did this in a custom SSLSocketFactory
I created:
我遇到了同样的问题。无论你是否为该SSLContext.init()
方法提供了 TLSv1.2 ,我尝试过的一些 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;
}
...
}