Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
android上的HttpClient和自定义TrustManager_Android_Ssl_Httpclient - Fatal编程技术网

android上的HttpClient和自定义TrustManager

android上的HttpClient和自定义TrustManager,android,ssl,httpclient,Android,Ssl,Httpclient,我一直在尝试向ApacheHttpClient库注册我的自定义TrustManger。以下链接包含有关如何执行此操作的说明: 不幸的是,我想要使用的构造函数(publicssslsocketfactory(sslcontextsslcontext))在HttpClient的Android版本中不可用。我将使用sslContext初始化我的自定义TrustManager。Android似乎已经用“密钥库”取代了这一功能 我的问题是:(如何)在Android中向DefaultHttpClient注册

我一直在尝试向ApacheHttpClient库注册我的自定义TrustManger。以下链接包含有关如何执行此操作的说明:

不幸的是,我想要使用的构造函数(publicssslsocketfactory(sslcontextsslcontext))在HttpClient的Android版本中不可用。我将使用sslContext初始化我的自定义TrustManager。Android似乎已经用“密钥库”取代了这一功能

我的问题是:(如何)在Android中向DefaultHttpClient注册自定义TrustManager?在KeyStore类中是否有其他选择

最终我想暂时忽略证书检查。。。
请只考虑我的整个应用程序是基于它的HtpPosiver库。

< P>解决方案是创建自己的套接字工厂。
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的SSLContext,然后创建一个AndroidHttpClient,并将其https模式替换为使用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;
    }
如果您不知道如何创建新的密钥库,请执行以下操作:

    /**
     * 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;
    }
/**
*获取当前密钥库,如果尚未创建,则创建一个新密钥库。这
*不会加载由标识的密钥库文件
*{@link#密钥库_NAME}。要加载密钥库文件,请使用函数
*{@link#loadKeyStore()}将自动调用此函数(因此
*你不需要)。
*
* 
*@返回一个{@link KeyStore}
*/
公共密钥库getKeyStore(){
if(mKeyStore!=null)
返回mKeyStore;
试一试{
字符串defaultType=KeyStore.getDefaultType();
mKeyStore=KeyStore.getInstance(defaultType);
mKeyStore.load(null,null);
}捕获(例外e){
Log.w(标记,e.getMessage());
}
返回mKeyStore;
}
上述解决方案是一个解决方案的开始,该解决方案允许您创建一个TrustManager,以验证“系统密钥库”以及您自己的“私有密钥库”(两个密钥库)的证书。然后,您不需要尝试向系统密钥库添加证书。您可以在getFilesDir()文件夹中创建自己的密钥库

我仍然没有完成捕获来自HttpResult=HttpClient.execute(HttpPost)的证书的逻辑;方法,但我现在正在积极地写这篇文章。如果你需要帮助,我现在也许可以和你一起做这件事


如果有人知道如何从HttpRequestBase对象中的SSLSocket捕获/获取证书,请告诉我。我正试图找到它。

实际上,该方法存在,但被隐藏。它由getHttpSocketFactory()在内部使用。我通过简单地使用反射来实现它。在一段时间内不安全,但出于开发目的可以

Class<org.apache.http.conn.ssl.SSLSocketFactory> c = org.apache.http.conn.ssl.SSLSocketFactory.class;
Constructor<org.apache.http.conn.ssl.SSLSocketFactory> ctor = c.getConstructor(javax.net.ssl.SSLSocketFactory.class);
SSLSocketFactory ssf = ctor.newInstance(SSLCertificateSocketFactory.getInsecure(getSSLHandshakeTimeout(), null));
Class c=org.apache.http.conn.ssl.SSLSocketFactory.Class;
Constructor=c.getConstructor(javax.net.ssl.SSLSocketFactory.class);
SSLSocketFactory ssf=ctor.newInstance(SSLCertificateSocketFactory.getUnsecure(getSSLHandshakeTimeout(),null));

安装自定义TrustManager的全部原因是为了避免证书检查。经过一周的博客、java代码和android源代码研究,发现问题实际上在于我连接的站点上ssl证书的排序。因此,如果您遇到证书验证问题,请始终仔细检查证书是否以正确的顺序提供给您,以及根证书是否存在于android设备上!我仍然对这个问题的答案感兴趣,我自己…@ivo我想我也有一个坏了的证书的问题!你做了什么来解决这个问题?你做过某种排序吗?@elton我让网站管理员重新排序证书,一切都很好。证书的顺序很容易检查,在一个我现在记不起名字的博客中有描述……从SSLSocket获得证书成功了吗?
Class<org.apache.http.conn.ssl.SSLSocketFactory> c = org.apache.http.conn.ssl.SSLSocketFactory.class;
Constructor<org.apache.http.conn.ssl.SSLSocketFactory> ctor = c.getConstructor(javax.net.ssl.SSLSocketFactory.class);
SSLSocketFactory ssf = ctor.newInstance(SSLCertificateSocketFactory.getInsecure(getSSLHandshakeTimeout(), null));