android - 在 Android 4.3 中获取 "No peer certificate"

标签 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 类 (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/

相关文章:

php - 媒体库未在 Wordpress 中显示 + 某些插件的图标

android - Fragments 的点击监听器

android - 加载程序在 Activity 启动时重新启动混淆

ssl - Azure Service Fabric 服务之间的 HTTPS

java - 通过 SSL 连接到站点时出错

email - 不支持使用 SMTP 和 TLS 从 Sonar 发送邮件?

android - 如何判断 "DP"中的屏幕分辨率?

android - Google Play 商店将允许带有 Targeted SDK 15 的应用程序进行生产发布?其中已经使用 Targeted SDK 23 提交了测试版应用程序

安卓异步WebView

python - 属性错误 : 'NoneType' object has no attribute 'connectSSL'