web-dev-qa-db-ja.com

Android ssl:javax.net.ssl.SSLPeerUnverifiedException:ピア証明書なし(まだ)

RESTfulサービスのsslを有効にするWebサイトを持っています。 RapidSSLに登録し、証明書をインストールすると、 RapidSSLチェッカー に合格します。 Androidブラウザ(組み込み、firefox、opera)など)を含むさまざまなブラウザで、問題なく警告なしでサイトにアクセスできます。

ただし、Androidアプリでアクセスしようとすると、次の例外が発生します。

08-11 20:04:05.586   363   381 E HttpProvider: Error executing request: No peer certificate
08-11 20:04:05.586   363   381 E HttpProvider: javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
08-11 20:04:05.586   363   381 E HttpProvider:  at org.Apache.harmony.xnet.provider.jsse.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.Java:259)
08-11 20:04:05.586   363   381 E HttpProvider:  at org.Apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.Java:93)
08-11 20:04:05.586   363   381 E HttpProvider:  at org.Apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.Java:381)
08-11 20:04:05.586   363   381 E HttpProvider:  at org.Apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.Java:164)
08-11 20:04:05.586   363   381 E HttpProvider:  at org.Apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.Java:164)
08-11 20:04:05.586   363   381 E HttpProvider:  at org.Apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.Java:119)
08-11 20:04:05.586   363   381 E HttpProvider:  at org.Apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.Java:359)
08-11 20:04:05.586   363   381 E HttpProvider:  at org.Apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.Java:555)
08-11 20:04:05.586   363   381 E HttpProvider:  at org.Apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.Java:487)
08-11 20:04:05.586   363   381 E HttpProvider:  at org.Apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.Java:465)
08-11 20:04:05.586   363   381 E HttpProvider:  at com.xxxxx.netlib.http.HttpProvider.executeRequest(HttpProvider.Java:75)

これはAndroid 2.3.3エミュレーターおよび3.2タブレットで発生します。これについて多くのヒットを見てきましたが、問題の解決に役立つものは見つかりませんでした。

より多くのデータ:

$ openssl s_client -CAfile www.xxxxx.com.pem -connect www.xxxxx.com:443
CONNECTED(00000003)
depth=3 C = US, O = Equifax, OU = Equifax Secure Certificate Authority
verify return:1
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify return:1
depth=1 C = US, O = "GeoTrust, Inc.", CN = RapidSSL CA
verify return:1
depth=0 serialNumber = 1-7wArtEjdTwJ94d5iVDooDmmC4mXyVj, OU = GT82425783, OU = See www.rapidssl.com/resources/cps (c)12, OU = Domain Control Validated - RapidSSL(R), CN = www.xxxxx.com
verify return:1
---
Certificate chain
0 s:/serialNumber=1-7wArtEjdTwJ94d5iVDooDmmC4mXyVj/OU=GT82425783/OU=See www.rapidssl.com/resources/cps (c)12/OU=Domain Control Validated - RapidSSL(R)/CN=www.xxxxx.com
  i:/C=US/O=GeoTrust, Inc./CN=RapidSSL CA
1 s:/C=US/O=GeoTrust, Inc./CN=RapidSSL CA
  i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
  i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
---
[snip]

クライアントをセットアップするために実行しているコード:

public class HttpProvider implements INetworkProvider {
  private static final String LOG = "HttpProvider";
  protected DefaultHttpClient client;

  public HttpProvider() {
    SchemeRegistry registry = new SchemeRegistry();
    registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
    final SSLSocketFactory sslSocketFactory = SSLSocketFactory.getSocketFactory();
    sslSocketFactory.setHostnameVerifier(SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
    registry.register(new Scheme("https", sslSocketFactory, 443));

    client = new DefaultHttpClient(
      new ThreadSafeClientConnManager((new BasicHttpParams()), registry), new BasicHttpParams()
    );
  }
[snip]

また、STRICT_HOSTNAME_VERIFIERを試してみましたが、まだ喜びはありません。

私が理解していることから、認定された証明書プロバイダーに登録されているため、カスタムのトラストストアまたはキーストアをセットアップする必要はありません。

私はsslに非常に慣れていないので、3文字の頭字語の海で泳いでいることがわかりました。ここの誰かが正しい方向に突き出してくれることを願っていました。

25
mvsjes2

掘り起こし、実験を重ねた結果、使用しているURLがデフォルトの443ではなく、ポート80がハードコードされていることに気づきました。

この質問に対する答え HTTPS経由でHttpClientを使用してすべての証明書を信頼する は、SSLを理解するのに非常に役立ちました。

18
mvsjes2