4

カスタムトラストストアを取り込むために作成したカスタムhttpclientがあり、アクセスしようとするすべてのSSLサイトで使用しています。そのためのコードは次のとおりです。

public class MyHttpClient extends DefaultHttpClient {

    private Context context;

    public MyHttpClient(Context context) {

        this.context = context;
    }

    @Override
    protected ClientConnectionManager createClientConnectionManager() {

        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", PlainSocketFactory
                .getSocketFactory(), 80));
        registry.register(new Scheme("https", newSslSocketFactory(), 443));
        return new SingleClientConnManager(getParams(), registry);
    }

    private SSLSocketFactory newSslSocketFactory() {

        try {
            KeyStore trusted = KeyStore.getInstance("BKS");
            InputStream in = context.getResources().openRawResource(
                    R.raw.cacerts);
            try {
                trusted.load(in, "changeit".toCharArray());
            }
            catch (CertificateException c) {
                System.out
                        .println("There was a certificate exception in myhttpclient!");
            }
            finally {

                in.close();
            }
            return new SSLSocketFactory(trusted);
            }
            catch (Exception e) {
                throw new AssertionError(e);
            }
    }
}

そして、これが私に与えているスタックトレースです:

W/System.err(4194): javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
W/System.err(4194):     at org.apache.harmony.xnet.provider.jsse.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:258)
W/System.err(4194):     at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:93)
W/System.err(4194):     at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:381)
W/System.err(4194):     at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:177)
W/System.err(4194):     at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
W/System.err(4194):     at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
W/System.err(4194):     at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:428)
W/System.err(4194):     at org.apache.http.impl.client.AbstractHttpClient$1.executeRequestSending(AbstractHttpClient.java:608)
W/System.err(4194):     at org.apache.http.impl.client.naf.redirect.NafRequestExecutorWrapperRedirectionHandler.executeRequestSendingUsual(NafRequestExecutorWrapperRedirectionHandler.java:96)
W/System.err(4194):     at org.apache.http.impl.client.naf.redirect.NafRequestExecutorWrapperRedirectionHandler.executeRequestSending(NafRequestExecutorWrapperRedirectionHandler.java:73)
W/System.err(4194):     at org.apache.http.impl.client.naf.auth.NafHttpAuthStrategyDefault.sendFirstRequest(NafHttpAuthStrategyDefault.java:487)
W/System.err(4194):     at org.apache.http.impl.client.naf.auth.NafHttpAuthStrategyDefault.performAuthExecutionUnsafe(NafHttpAuthStrategyDefault.java:388)
W/System.err(4194):     at org.apache.http.impl.client.naf.auth.NafHttpAuthStrategyDefault.performAuthExecution(NafHttpAuthStrategyDefault.java:200)
W/System.err(4194):     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:556)
W/System.err(4194):     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:505)
W/System.err(4194):     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:483)
W/System.err(4194):     at com.wmmccreedy.vce.AgConnection.submitInfo(AgConnection.java:111)
W/System.err(4194):     at com.wmmccreedy.vce.LoginSubmitActvity$DownloadWebPageTask.doInBackground(LoginSubmitActvity.java:199)
W/System.err(4194):     at com.wmmccreedy.vce.LoginSubmitActvity$DownloadWebPageTask.doInBackground(LoginSubmitActvity.java:1)
W/System.err(4194):     at android.os.AsyncTask$2.call(AsyncTask.java:185)
W/System.err(4194):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
W/System.err(4194):     at java.util.concurrent.FutureTask.run(FutureTask.java:138)
W/System.err(4194):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
W/System.err(4194):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
W/System.err(4194):     at java.lang.Thread.run(Thread.java:1019)

さて、これは正しく機能します...時間の約50%。whileループを作成することで、これを「解決」しました。それはhttpclientクライアントを再作成し続け、それが機能するまで、通常は1〜2回の試行の後(私が見た最大は4回)、サーバーに何度もアクセスしようとします。明らかに、これは非常に非効率的です。

問題を上記のクラスに絞り込みました。httpclientを1回だけ作成し、同じクラスを複数回使用してサイトにアクセスしようとすると、失敗するか、成功するかによって異なります。 「良い」httpclientまたは「悪い」httpclientを取得しました。ただし、Webページにアクセスしようとするたびにhttpclientを作成すると、機能する場合と機能しない場合があります。

では、なぜこれを行うのでしょうか。また、どうすればこれを修正できますか?そして、なぜそれが断続的にしか機能しないのですか、クライアントの作成間で何が変わる可能性がありますか?

編集:解決しました!

トラストストアにいくつかのエイリアスの古いバージョンを残していたようですが、最初に見つけたエイリアスをランダムに選択していましたが、必ずしも正しいものになるとは限りませんでした。各エイリアスにはすべて同じ証明書が含まれていましたが、それぞれに異なる順序ですべての証明書が含まれていました。正しいストアが見つかるまでテストし、残りを削除しました。これですべてが完璧になりました。

4

2 に答える 2

2

これは「証明書の作成」の問題ではありません。

サーバー(ピア)は証明書を送信しませんでした。これは、トラストストアによって信頼されている誰かによって署名されたキーストアで1つが見つからなかったことが原因である可能性があります。

于 2012-05-27T08:10:02.437 に答える
0

これは、Apache HTTPクライアント(Android 2.3で観察)の問題です。キーストアをロードすると、証明書はランダムな順序でメモリデータ構造にロードされます。ApacheHTTPクライアントのPKIXパス検証ロジックに障害があります。サーバーの証明書から始まり、キーストアを調べます。最初に検索される証明書がCA証明書である場合、チェーンは正常に構築され、検証は成功します。ただし、最初に検索される証明書がサーバーの証明書である場合、ApacheHTTPクライアントはあきらめます。検証は失敗します。

したがって、キーストアにサーバーおよび中間CA証明書がないことを確認してください。

于 2014-10-08T12:42:46.507 に答える