在Android 4.3中获取“无对等证书”

时间:2013-10-22 10:25:55

标签: android ssl

我想通过证书连接到经过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/

1 个答案:

答案 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异常消失了。