2

androidでhttpclientを使用してsslに問題があります。自己署名証明書に詳細にアクセスしようとしています。アプリにすべての証明書を信頼させたいです(sslはデータの暗号化にのみ使用します)。最初にこのガイドを使用してみましたhttp://hc.apache.org/httpclient-3.x/sslguide.htmlデスクトップでは正常に動作していますが、Androidではまだjavax.net.ssl.SSLException:信頼できないサーバー証明書を取得しています。グーグルで検索した後、私はSSLを有効にする方法の他のいくつかの例を見つけました。

http://groups.google.com/group/android-developers/browse_thread/thread/62d856cdcfa9f16e-URLConnectionを使用しているが、HttpClientを使用している場合でも例外が発生します。

http://www.discursive.com/books/cjcook/reference/http-webdav-sect-self-signed.html-Apacheのjarを使用するデスクトップでは機能していますが、AndroidではSDKクラスに含まれているものを使用しても機能しません。

http://mail-archives.apache.org/mod_mbox/hc-httpclient-users/200808.mbox/%3C1218824624.6561.14.camel@ubuntu%3E-同じ例外が発生します

だから、どのように私はHttpClientを使用してAndroid上のすべての証明書を信頼することができますか

4

3 に答える 3

9

DefaultHttpClient のコードを見ると、次のようになっています。

   @Override
    protected ClientConnectionManager createClientConnectionManager() {
        SchemeRegistry registry = new SchemeRegistry();
        registry.register(
                new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        registry.register(
                new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));

        ClientConnectionManager connManager = null;     
        HttpParams params = getParams();
        ...
    }

https スキームの org.apache.http.conn.ssl.SSLSocketFactory.getSocketFactory() へのマッピングに注意してください。

org.apache.commons.httpclient.protocol.SecureProtocolSocketFactoryインターフェイス ( http://hc.apache.org/httpclient-3.x/apidocs/org/apache/commons/httpclient/protocol/SecureProtocolSocketFactory.html )のjava.net.SSLSocketカスタム実装を作成TrustManagerできます。すべての証明書を受け入れます。

詳細については、 http://java.sun.com/j2se/1.4.2/docs/guide/security/jsse/JSSERefGuide.htmlで JSSE を調べてください。

于 2010-05-19T10:10:01.560 に答える
3

重要なアイデアは、LayeredSocketFactory を実装するカスタマイズされた SSLSocketFactory を使用することです。カスタマイズされたソケットは HostNameVerifier を必要としません。

private static final class TrustAllSSLSocketFactory implements
    LayeredSocketFactory {

    private static final TrustAllSSLSocketFactory DEFAULT_FACTORY = new TrustAllSSLSocketFactory();

    public static TrustAllSSLSocketFactory getSocketFactory() {
        return DEFAULT_FACTORY;
    }

    private SSLContext sslcontext;
    private javax.net.ssl.SSLSocketFactory socketfactory;

    private TrustAllSSLSocketFactory() {
        super();
        TrustManager[] tm = new TrustManager[] { new X509TrustManager() {

            @Override
            public void checkClientTrusted(X509Certificate[] chain,
                String authType) throws CertificateException {
                // do nothing
            }

            @Override
            public void checkServerTrusted(X509Certificate[] chain,
                String authType) throws CertificateException {
                // do nothing
            }

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }

        } };
        try {
            this.sslcontext = SSLContext.getInstance(SSLSocketFactory.TLS);
            this.sslcontext.init(null, tm, new SecureRandom());
            this.socketfactory = this.sslcontext.getSocketFactory();
        } catch ( NoSuchAlgorithmException e ) {
            Log.e(LOG_TAG,
                "Failed to instantiate TrustAllSSLSocketFactory!", e);
        } catch ( KeyManagementException e ) {
            Log.e(LOG_TAG,
                "Failed to instantiate TrustAllSSLSocketFactory!", e);
        }
    }

    @Override
    public Socket createSocket(Socket socket, String host, int port,
        boolean autoClose) throws IOException, UnknownHostException {
        SSLSocket sslSocket = (SSLSocket) this.socketfactory.createSocket(
            socket, host, port, autoClose);
        return sslSocket;
    }

    @Override
    public Socket connectSocket(Socket sock, String host, int port,
        InetAddress localAddress, int localPort, HttpParams params)
        throws IOException, UnknownHostException, ConnectTimeoutException {
        if ( host == null ) {
            throw new IllegalArgumentException(
                "Target host may not be null.");
        }
        if ( params == null ) {
            throw new IllegalArgumentException(
                "Parameters may not be null.");
        }

        SSLSocket sslsock = (SSLSocket) ( ( sock != null ) ? sock
            : createSocket() );

        if ( ( localAddress != null ) || ( localPort > 0 ) ) {

            // we need to bind explicitly
            if ( localPort < 0 ) {
                localPort = 0; // indicates "any"
            }

            InetSocketAddress isa = new InetSocketAddress(localAddress,
                localPort);
            sslsock.bind(isa);
        }

        int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
        int soTimeout = HttpConnectionParams.getSoTimeout(params);

        InetSocketAddress remoteAddress;
        remoteAddress = new InetSocketAddress(host, port);

        sslsock.connect(remoteAddress, connTimeout);

        sslsock.setSoTimeout(soTimeout);

        return sslsock;
    }

    @Override
    public Socket createSocket() throws IOException {
        // the cast makes sure that the factory is working as expected
        return (SSLSocket) this.socketfactory.createSocket();
    }

    @Override
    public boolean isSecure(Socket sock) throws IllegalArgumentException {
        return true;
    }

}

その後、サポートされているスキーム レジストリで、カスタマイズされた SSLSocketFactory を引き続き使用できます。

private static final BasicHttpParams sHttpParams = new BasicHttpParams();
private static final SchemeRegistry sSupportedSchemes = new SchemeRegistry();
static {
    sHttpParams.setParameter("http.socket.timeout", READ_TIMEOUT);
    sHttpParams.setParameter("http.connection.timeout", CONNECT_TIMEOUT);
    sSupportedSchemes.register(new Scheme("http",
        PlainSocketFactory.getSocketFactory(), 80));
    sSupportedSchemes.register(new Scheme("https",
        TrustAllSSLSocketFactory.getSocketFactory(), 443));
}
于 2011-04-26T17:08:33.973 に答える
2

すべての証明書を受け入れるのではなく、次のソリューションをお勧めします。HTTPS経由でHttpClientを使用してすべての証明書を信頼する

于 2011-06-16T21:40:00.873 に答える