2012-08-04 9 views
7

私のAndroidプロジェクトでapiが使用されています15. HttpsURLConnectionクラスを使用してhttpsでサーバーに接続しています。すべてはWiFi経由でうまく動作しますが、私は無線LANをオフにして、3グラム上で実行する場合、私は、次を得る:3g以上使用しても証明書パスの信頼アンカーが見つかりませんでしたが、WiFi上で正常に動作します

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.  at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:413) 
    at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:257)  at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:210) 
    at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:477) 
    at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:432) 
    at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282) 
    at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:232)  at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:80) 
    at libcore.net.http.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:188)  at libcore.net.http.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:280) 

私が何か間違ったことをやっている場合は、なぜそれがWiFi経由で動作するでしょうか?

ここにもう少し詳しい情報があります。

echo | openssl s_client -connect myserver.com:443 -servername myserver.com 

が「正しい」証明書を返すのに対し、

私は、サーバー証明書の情報を表示するためにOpenSSLを使用している場合は、

echo | openssl s_client -connect myserver.com:443 

は、サーバーレベルの自己署名証明書を返します。私はサーバ上に複数の仮想ホストを持っていますが、それぞれが独自のRapidsSlashで発行された証明書を持っていますので、TLS対応のクライアントを使用する必要があります。少なくとも、私は起動時に私のApacheのログに表示メッセージの私の解釈です:

Name-based SSL virtual hosts only work for clients with TLS server name indication support 

私がこれまで正しいだ場合、それは私の携帯電話の3Gネットワ​​ークは、TLSでねじ込むことができ、または何か他のものがあるわけありません私はやっているはずですか?

私は物事がDefaultHttpClientをサブクラス化し、サーバの自己署名証明書を含むキーストアをインポートすることにより、3グラム上で動作するように取得することができますが、それは間違いなく私の好ましい選択肢ではありません。

+0

サーバーのURLは何ですか。 – jww

答えて

0

-servernameオプションを追加すると、Client HelloのメッセージにServer Name Indicationというフィールドが設定されるだけで、目的のホストに多くの場合、正しい証明書を選択するのに役立ちます。しかし、それは問題に関連していません。

SSLハンドシェイク時に、証明書がサブジェクト/発行者のペアで配信され、証明書チェーンが形成されます。

I.e. google.com証明書チェーンは次のようになります。

openssl s_client -connect google.com:443 
CONNECTED(00000003) 
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA 
verify error:num=20:unable to get local issuer certificate 
verify return:0 
--- 
Certificate chain 
0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.google.com 
    i:/C=US/O=Google Inc/CN=Google Internet Authority G2 
1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2 
    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 
--- 

が一度受信、クライアントが(ルート)を下から上にチェーン内のすべての発行体を検証しようとします。クライアントがルート証明書を検証できなかった場合は、Trust anchor for certification path not foundというメッセージが表示されます。

したがって、WiFi/3Gの問題に戻ると、おそらくモバイルネットワークのDNSが、証明書チェーンの中間発行者のアドレスを解決できなかった可能性があります。

UPDATE:

あなたのAPKにあなたの発行体の証明書を入れて、あなたのコード内でTrustManagerを経由して追加することができます。このアプローチは、アクセスネットワークの制限(存在する場合)を克服する可能性があります。

+0

DNSと証明書の検証はまったくどのような関係がありますか? – EJP

+0

中間証明書の1つがデバイスCAキーストアに存在しない場合、どのプロトコルによって権限が検出されますか?さらに、この回答を確認してください:http://stackoverflow.com/questions/19220687/is-domain-name-of-the-server-checked-during-ssl-handshake –

関連する問題