Android 4.0中的SSL客户端身份验证已损坏

时间:2012-01-08 11:00:00

标签: java android ssl

我有一个Android应用程序,它使用SSLSocketFactory加载pkcs12证书并使用该证书对我的服务器执行SSL客户端身份验证。这个过程在Android 2.1,2.2和2.3上完美运行,但是当我尝试在运行4.0的手机或模拟器上运行此代码时,我的服务器没有从我的应用程序发出的请求中收到公钥。

这是我用来获取我用来执行请求的HttpClient的代码

private HttpClient getHttpClient(Context context) {
    if(httpClient == null) {
        KeyStore mycert = KeyStore.getInstance("pkcs12");
        byte[] pkcs12 = persistentStorage.getPKCS12Certificate(context);

        ByteArrayInputStream pkcs12BAIS = new ByteArrayInputStream(pkcs12);
        mycert.load(pkcs12BAIS, config.getPassword().toCharArray());

        SSLSocketFactory sockfact = new SSLSocketFactory(mycert, null, null);

        sockfact.setHostnameVerifier(new StrictHostnameVerifier());

        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("https",sockfact , config.getPort()));

        BasicHttpParams httpParameters = new BasicHttpParams();
        HttpProtocolParams.setUseExpectContinue(httpParameters, false);
        HttpProtocolParams.setVersion(httpParameters, HttpVersion.HTTP_1_1);

        HttpConnectionParams.setConnectionTimeout(httpParameters, 3000);
        HttpConnectionParams.setSoTimeout(httpParameters, 3000);

        ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(httpParameters, registry);
        cm.closeExpiredConnections();
        cm.closeIdleConnections(3000, TimeUnit.MILLISECONDS);

        httpClient = new DefaultHttpClient(cm, httpParameters);

    }

    return httpClient;
}

2 个答案:

答案 0 :(得分:2)

请注意,在Android 3.0(API级别11)之后,网络操作在UI线程上受到限制。您是否有机会在UI线程上调用网络操作?

自API级别9以来引入了

StrictMode.ThreadPolicy,并且自API级别11以来默认的线程策略已经更改,简而言之,不允许在UI线程上执行网络操作(包括HttpClient和HttpUrlConnection)。如果你这样做,你会得到NetworkOnMainThreadException。

始终建议将网络操作从UI线程移开,例如,使用AsyncTask。

希望得到这个帮助。

答案 1 :(得分:1)

事实证明,从ICS开始,SSLSocketFactory(或系统的其他部分)将不再正确接受未签名的x509证书(我用它来创建pkcs12证书)。我只需要自我签署证书,我现有的Java代码工作正常。