我想通过证书连接到经过SSL认证的服务器。
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.params.BasicHttpParams;
[...]
SchemeRegistry registry = new SchemeRegistry();
SSLSocketFactory sslSocketFactory = new SSLSocketFactory( keyStore, profile.getIdentityPassPhrase(), trustStore );
sslSocketFactory.setHostnameVerifier( new AllowAllHostnameVerifier() );
registry.register( new Scheme( "http", PlainSocketFactory.getSocketFactory(), 80) );
registry.register( new Scheme( "https", sslSocketFactory, 443 ) );
// Create a new HttpClient and Post Header
HttpParams httpParams = new BasicHttpParams();
httpParams.setBooleanParameter( "http.protocol.expect-continue", true );
HttpProtocolParams.setVersion( httpParams, HTTP_VERSION );
HttpProtocolParams.setContentCharset( httpParams, CONTENT_CHARSET );
HttpConnectionParams.setConnectionTimeout( httpParams, TIMEOUT_MILLISEC );
HttpConnectionParams.setSoTimeout( httpParams, TIMEOUT_MILLISEC );
httpClient = new DefaultHttpClient( new ThreadSafeClientConnManager( httpParams, registry ), httpParams );
在Android 4.2.2(及更低版本)中,它运行正常。但是在Android 4.3上会抛出错误消息
javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
错误在哪里?为什么它适用于API 17及更低版本,但不适用于API 18?
编辑执行// execute // - function时,在HttpClient-class(org.apache.http.client)中抛出异常。这些功能在4.3中有什么变化但在4.2.2中没有变化? Android GIT表示没有重要的变化:https://android.googlesource.com/platform/external/apache-http/
答案 0 :(得分:1)
我找到了解决问题的方法。我使用openssl s_client -connect my_server.com:443 -CApath /etc/ssl/certs/
来检查我的ssl证书。它返回了错误的证书!事实证明,我在同一个ip上设置了两个不同的vsost,并使用不同的ssl证书。这需要客户端处理此问题:http://en.wikipedia.org/wiki/Server_Name_Indication。
事实证明Android似乎没有处理这个问题,至少在使用这段代码时是这样的:
String responseString = "";
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
try {
response = httpclient.execute(new HttpGet(uri[0]));
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK || statusLine.getStatusCode() == 428){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
} else{
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
Log.e("err",e.getMessage());
} catch (IOException e) {
Log.e("err",e.getMessage());
}
return responseString;
我删除了第二个vHost,以便在每种情况下只从服务器返回一个证书。现在javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
异常消失了。