java - 带有 TLSv1.2 问题的 Android < 5.0 (Lollipop) 中的套接字握手
问题描述
我使用下面的代码创建一个到服务器的套接字并获取服务器公钥(服务器 TLS 版本是 1.2)。
问题出在 Android < 5.0 中socket.startHandshake();
catch error : javax.net.ssl.SSLException: Connection closed by peer.
我搜索了很多,发现我必须强制 Android < 5 使用 TLSv1.2,但我不能这样做(+、+、+)。
SSLSocketFactory factory = HttpsURLConnection.getDefaultSSLSocketFactory();
SSLSocket socket = (SSLSocket) factory.createSocket(hostname, 443);
socket.setSoTimeout(10000);
socket.startHandshake();
Certificate[] certs = socket.getSession().getPeerCertificates();
Certificate cert = certs[0];
PublicKey serverKey = cert.getPublicKey();
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = context.getResources().getAssets().open("filename.cert");
Certificate ca;
ca = cf.generateCertificate(caInput);
if (String.valueOf(serverKey).equals(String.valueOf(ca.getPublicKey()))) {
My codes ...
}
我怎样才能做到这一点?谢谢。
解决方案
您应该在 Android KitKat 及以下版本上强制使用 TLSv1.2,如下所示:
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
socket.setEnabledProtocols(new String[]{"TLSv1.2"});
}
https://developer.android.com/reference/javax/net/ssl/SSLSocket.html
干杯!
推荐阅读
- intellij-idea - IntelliJ IDEA 社区版
- go - golang中的死锁
- amazon-redshift - 卸载与 sqlContext 读取之间的性能
- sql-server - 将参数转换为十进制类型而不进行四舍五入
- c - 漏洞利用技术中的代码问题
- actions-on-google - 尽管经过验证和几天的等待,Android 应用程序并未显示为已连接的应用程序
- node.js - Nodejs上的多个setTimeouts
- php - 尝试制作简单的评分系统时出现 PHP 错误 500
- c++ - 将带有可变参数模板参数的 std::tuple 作为其元素类型传递给另一个函数作为参数列表
- google-cloud-platform - 如何将文件从 Google Cloud 复制到本地机器?(云壳)