2

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

4

1 回答 1

1

我找到了解决我的问题的方法。我曾经openssl s_client -connect my_server.com:443 -CApath /etc/ssl/certs/检查过我的 ssl 证书。它返回了错误的证书!事实证明,我在同一个 ip 上设置了两个不同的 vHost,并使用不同的 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异常消失了。

于 2014-01-01T19:11:25.043 回答