【发布时间】:2017-06-08 11:57:27
【问题描述】:
我无法在 Android 6 应用程序和安全服务器之间建立连接,其中服务器使用 Java (jdk 1.6) keytool 命令生成的自签名证书。 Android 6 应用显示以下错误。
异常日志:
javax.net.ssl.SSLHandshakeException: Handshake failed : javax.net.ssl.SSLHandshakeException: Handshake failed
05-23 17:21:03.498 3602-6487/issac.wise.pay I/System.out: at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:429)
05-23 17:21:03.498 3602-6487/issac.wise.pay I/System.out: at com.android.okhttp.Connection.connectTls(Connection.java:235)
05-23 17:21:03.498 3602-6487/issac.wise.pay I/System.out: at com.android.okhttp.Connection.connectSocket(Connection.java:199)
05-23 17:21:03.498 3602-6487/issac.wise.pay I/System.out: at com.android.okhttp.Connection.connect(Connection.java:172)
05-23 17:21:03.498 3602-6487/issac.wise.pay I/System.out: at com.android.okhttp.Connection.connectAndSetOwner(Connection.java:367)
05-23 17:21:03.498 3602-6487/issac.wise.pay I/System.out: at com.android.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:130)
05-23 17:21:03.498 3602-6487/issac.wise.pay I/System.out: at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:329)
05-23 17:21:03.498 3602-6487/issac.wise.pay I/System.out: at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:246)
05-23 17:21:03.498 3602-6487/issac.wise.pay I/System.out: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:457)
05-23 17:21:03.498 3602-6487/issac.wise.pay I/System.out: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:126)
05-23 17:21:03.498 3602-6487/issac.wise.pay I/System.out: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:257)
05-23 17:21:03.498 3602-6487/issac.wise.pay I/System.out: at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getOutputStream(DelegatingHttpsURLConnection.java:218)
05-23 17:21:03.498 3602-6487/issac.wise.pay I/System.out: at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java)
我正在使用下面的代码,它在 android 5.9 之前运行良好,但它不适用于 android 6(marshmallow);以下链接提供了与 ssl 通信的代码 -
https://developer.android.com/training/articles/security-ssl.html
// Load CAs from an InputStream
// (could be from a resource or ByteArrayInputStream or ...)
CertificateFactory cf = CertificateFactory.getInstance("X.509");
// From https://www.washington.edu/itconnect/security/ca/load-der.crt
InputStream caInput = new BufferedInputStream(new FileInputStream("load-der.crt"));
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
// Tell the URLConnection to use a SocketFactory from our SSLContext
URL url = new URL("https://certs.cac.washington.edu/CAtest/");
HttpsURLConnection urlConnection =
(HttpsURLConnection)url.openConnection();
urlConnection.setSSLSocketFactory(context.getSocketFactory());
InputStream in = urlConnection.getInputStream();
copyInputStreamToOutputStream(in, System.out);
有人可以建议如何解决这个问题吗?这是任何证书生成问题还是我需要遵循任何新技术与服务器通信?
【问题讨论】:
-
“它在 android 5.9 之前运行良好”——没有 Android 5.9。 “以下链接提供了与 ssl 通信的代码”——这不是您的代码,除非您尝试与华盛顿大学 CA 测试服务器通信。相反,这似乎是您从the documentation 复制的代码。除非我们能看到 your 代码,否则我们无法帮助您解决 your 与 your 代码有关的问题。
-
“这是任何证书生成问题还是我需要遵循任何新技术与服务器通信?” ——我想不出Android 6.0有什么变化。 Android 的 network security configuration 在这里提供了新选项,但这是 Android 7.0 的新选项,尽管 I have backported it to Android 4.2。
标签: android ssl android-6.0-marshmallow self-signed