我想连接到带有证书的 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 类 (org.apache.http.client) 中抛出异常。这些功能在 4.3 中发生了什么变化,但在 4.2.2 中没有? Android GIT 表示没有重要变化:https://android.googlesource.com/platform/external/apache-http/
最佳答案
我找到了解决问题的方法。我使用 openssl s_client -connect my_server.com:443 -CApath/etc/ssl/certs/
检查我的 ssl 证书。它返回了错误的证书!事实证明,我在同一个 ip 上设置了两个不同的 vHosts 和不同的 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
异常消失了。
关于android - 在 Android 4.3 中获取 "No peer certificate",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19515215/