我有一个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;
}
答案 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代码工作正常。