HttpClient的和安卓定制的TrustManager [英] HttpClient and custom TrustManager on android

查看:261
本文介绍了HttpClient的和安卓定制的TrustManager的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试注册我的自定义TrustManger与Apache HttpClient库。下面的链接包含有关如何执行此方向: HTTPS连接的Andr​​oid

I've been trying to register my custom TrustManger with the apache HttpClient library. The following link contains directions on how to perform this: Https Connection Android

不幸的是,构造我想用(公共的SSLSocketFactory(的SSL连接的SSL连接))是不是在HttpClient的Andr​​oid版本可用。我会用的SSL连接来初始化我的自定义的TrustManager。看来Android已经由一个密钥库取代这一点。

Unfortunately the constructor I would like to use ( public SSLSocketFactory(SSLContext sslContext) ) is not available in the Android version of HttpClient. I would use a sslContext to initialize my custom TrustManager. It seems Android has replaced this by a 'KeyStore'.

我的问题是:(如何做)我可以在Android的注册自定义TrustManger与DefaultHttpClient?有密钥库类的替代地方?

My question is: (how) can I register a custom TrustManger with DefaultHttpClient in Android? Is there an alternative somewhere in the KeyStore classes?

最后,我想忽略证书检查现在... 请只考虑HttpClient库,因为我的整个应用程序是基于它。

Ultimately I would like to ignore the certificate checking for now... Please only consider the HttpClient library since my whole app is based on it.

推荐答案

解决方案是创建自己的套接字工厂。

The solution is to create your own socket factory.

public class NetworkSSLSocketFactory implements LayeredSocketFactory {

    private SSLContext sslContext;
    private SSLSocketFactory socketFactory;
    private X509HostnameVerifier hostnameVerifier;

    /**
     * Creates a socket factory that will use the {@link SSLContext} and
     * {@link X509HostnameVerifier} specified. The SSLContext provided should
     * have the {@link NetworkTrustManager} associated with it.
     * 
     * @param sslContext
     * @param hostnameVerifier
     */
    public NetworkSSLSocketFactory(SSLContext sslContext,
            X509HostnameVerifier hostnameVerifier) {
        this.sslContext = sslContext;
        this.socketFactory = sslContext.getSocketFactory();
        this.hostnameVerifier = hostnameVerifier;
    }  
}

然后创建一个使用你的TrustManager一个的SSL连接,然后创建一个AndroidHttpClient,并与一个使用您的SocketFactory更换其HTTPS模式。

Then create an SSLContext that uses your TrustManager and then create a AndroidHttpClient and replace its https schema with one that uses your SocketFactory.

    /**
     * Return the SSLContext for use with our HttpClient or create a new Context
     * if needed.
     * <p>
     * This context uses our {@link NetworkTrustManager}
     * 
     * @return an {@link SSLContext}
     */
    public SSLContext getSSLContext() {

        if (mSSLContextInstance != null)
            return mSSLContextInstance;

        try {
            mSSLContextInstance = SSLContext.getInstance("TLS");
            TrustManager trustManager = new NetworkTrustManager(getKeyStore());
            TrustManager[] tms = new TrustManager[] { trustManager };
            mSSLContextInstance.init(null, tms, new SecureRandom());
        } catch (NoSuchAlgorithmException e) {
            Log.e(TAG, e.getMessage());
        } catch (KeyManagementException e) {
            Log.e(TAG, e.getMessage());
        }

        return mSSLContextInstance;
    }

现在的客户端

/**
 * Return an HttpClient using our {@link NetworkTrustManager} and
 * {@link NetworkHostnameVerifier}
 * 
 * @return an {@link HttpClient}
 */
public HttpClient getHttpClient() {

    if (mHttpClientInstance != null)
        return mHttpClientInstance;

    SSLContext sslContext = getSSLContext();

    // Now create our socket factory using our context.
    X509HostnameVerifier hostnameVerifier = new NetworkHostnameVerifier();
    NetworkSSLSocketFactory sslSocketFactory = new NetworkSSLSocketFactory(
            sslContext, hostnameVerifier);

    // Some services (like the KSOAP client) use the HttpsURLConnection
    // class
    // to establish SSL connections.
    HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
    HttpsURLConnection.setDefaultSSLSocketFactory(sslContext
            .getSocketFactory());

    // Generate the Client for the Server
    mHttpClientInstance = AndroidHttpClient.newInstance(getAgent(),
            mContext);

    // Get the registry from the AndroidHttpClient and change the
    // HTTPS scheme to use our socket factory. This way we can
    // control the certificate authority and trust system.
    SchemeRegistry schemeRegistry = mHttpClientInstance
            .getConnectionManager().getSchemeRegistry();

    schemeRegistry.register(new Scheme("https", sslSocketFactory, 443));

    return mHttpClientInstance;
}

如果您不知道如何创建一个新的密钥库,在这里你去:

If you don't know how to create a new keystore, here you go:

    /**
     * Get the current KeyStore or if not yet created, create a new one. This
     * will <b>NOT</b> load the KeyStore file identified by
     * {@link #KEYSTORE_NAME}. To load the KeyStore file, use the function
     * {@link #loadKeyStore()} which will automatically call this function (so
     * you don't need to).
     * <p>
     * 
     * @return a {@link KeyStore}
     */
    public KeyStore getKeyStore() {

        if (mKeyStore != null)
            return mKeyStore;

        try {
            String defaultType = KeyStore.getDefaultType();
            mKeyStore = KeyStore.getInstance(defaultType);
            mKeyStore.load(null, null);
        } catch (Exception e) {
            Log.w(TAG, e.getMessage());
        }

        return mKeyStore;
    }

以上的解决方案是一个解决方案,允许您创建的TrustManager,将验证证书系统密钥库,以及你自己的专用的密钥库(两个密钥库)的开始。然后,你不必试图证书添加到系统密钥库中。您可以在getFilesDir()文件夹中创建自己的密钥库。

The above solution is the beginning of a solution that allows you to create a TrustManager that will validate certificates to the "System KeyStore" as well as you own "Private KeyStore" (two keystores). Then, you don't need to try to add certificates to the System KeyStore. You can create your own KeyStore in your getFilesDir() folder.

我还没有从Htt的presult = HttpClient.execute(HttpPost)完成套住证书的逻辑;方法,但我积极现在写这个。如果你需要帮助,我也许能现在与您合作这一点。

I still don't have the logic finished to trap the Certificate from the HttpResult = HttpClient.execute(HttpPost); method, but I am actively writing this now. If you need help, I might be able to work this with you now.

如果有人知道如何捕获/获得证书从SSLSocekt的Htt的prequestBase对象中,请让我知道。我试图追捕下来。

If someone knows how to trap/get the Certificate from the SSLSocekt within the HttpRequestBase object, please let me know. I'm trying to hunt this down.

这篇关于HttpClient的和安卓定制的TrustManager的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆