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

一笑奈何 提交于 2019-11-30 17:53:19

问题


I am trying to work out recipes for using SNI with major HTTP stacks on modern versions of Android. This includes Apache's separate HttpClient library (not the version baked into Android itself, which is dead and gone).

It appears that recent versions of HttpClient do not support SNI out of the box. When I use the 'cz.msebera.android:httpclient:4.4.1.1' artifact, I get:

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)

(host names redacted with ...)

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 helps a bit with an implementation. However, that in turn crashes with an equivalent exception:

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 does not surprise me. The proposed workaround (replace the real host name with the empty string) struck me as rather odd.

This Stack Overflow question-and-answer basically say "use Java 1.7", which is not a viable option for Android.

So, has anyone worked out a recipe for enabling SNI with an Android-compatible HttpClient 4.4+ environment?


回答1:


Try using this version of SSLConnectionSocketFactory instead of the one shipped with Marek Sebera's fork of HttpClient. It contains this Andriod specific bit of code. Last time I tested SNI with the official Apache port of HttpClient 4.3 it worked just fine.

// 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


来源:https://stackoverflow.com/questions/35782882/how-do-we-enable-sni-in-httpclient-4-4-on-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!