我正在尝试制定在现代版本的 Android 上将 SNI 与主要 HTTP 堆栈结合使用的方法。这包括 Apache 的单独 HttpClient 库(not该版本嵌入到 Android 本身中,但 Android 已经死亡并消失了)。
最新版本的 HttpClient 似乎不支持开箱即用的 SNI。当我使用'cz.msebera.android:httpclient:4.4.1.1'
神器,我得到:
javax.net.ssl.SSLPeerUnverifiedException: Host name '...' does not match the certificate subject provided by the peer (CN=...)
at cz.msebera.android.httpclient.conn.ssl.SSLConnectionSocketFactory.verifyHostname(SSLConnectionSocketFactory.java:466)
at cz.msebera.android.httpclient.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:395)
(主机名经过编辑...
)
这个 HttpClient 问题有一些代码旨在解决这个问题。但具体如何使用尚不清楚。这个堆栈溢出答案对实施有一点帮助。然而,这又会崩溃并出现一个等效的异常:
javax.net.ssl.SSLPeerUnverifiedException: Host name '' does not match the certificate subject provided by the peer (CN=...)
at cz.msebera.android.httpclient.conn.ssl.SSLConnectionSocketFactory.verifyHostname(SSLConnectionSocketFactory.java:466)
at cz.msebera.android.httpclient.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:395)
这并不令我感到惊讶。所提出的解决方法(用空字符串替换真实主机名)让我觉得相当奇怪。
这个 Stack Overflow 问答基本上是说“使用Java 1.7”,这对于Android来说不是一个可行的选择。
那么,有没有人研究出在 Android 兼容的 HttpClient 4.4+ 环境中启用 SNI 的方法?
尝试使用这个版本SSLConnectionSocketFactory而不是 Marek Sebera 的 HttpClient 分支附带的那个。它包含这段 Andriod 特定的代码。上次我使用 HttpClient 4.3 的官方 Apache 端口测试 SNI,效果很好。
// Android specific code to enable SNI
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Enabling SNI for " + target);
}
try {
Method method = sslsock.getClass().getMethod("setHostname", String.class);
method.invoke(sslsock, target);
} catch (Exception ex) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "SNI configuration failed", ex);
}
}
}
// End of Android specific code
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)