我们如何在 Android 上的 HttpClient 4.4+ 中启用 SNI?

How Do We Enable SNI in HttpClient 4.4+ on Android?

我正在尝试制定在 Android 的现代版本上将 SNI 与主要 HTTP 堆栈结合使用的方法。这包括 Apache 的单独 HttpClient 库( 不是 版本烘焙到 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)

(用 ... 编辑的主机名)

This HttpClient issue has some code that purports to address this. However, it is not clear exactly how to use it. This Stack Overflow answer 有助于实现。但是,这又会因等效异常而崩溃:

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)

这并不让我吃惊。建议的解决方法(用空字符串替换真实主机名)让我觉得很奇怪。

This Stack Overflow question-and-answer 基本上说 "use 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