Android HTTPS帖子 - 不工作

时间:2011-11-22 05:30:22

标签: android post ssl https

我已经尝试了很长时间才能让它发挥作用 - 但无论我做什么,我的HTTP * S * POST总会产生  HttpUtils: javax.net.ssl.SSLException: Not trusted server certificate

基本上我遵循了tutorial

  • 我成功地抓住了公共证书(mycert.pem) 服务器。
  • 我使用Bouncy Castle
  • 从证书中成功创建了一个密钥库
  • 我在实现自定义Apache HttpClient时失败了。这是我的 代码:

    import android.content.Context;
    import org.apache.http.conn.ClientConnectionManager;
    import org.apache.http.conn.scheme.PlainSocketFactory;
    import org.apache.http.conn.scheme.Scheme;
    import org.apache.http.conn.scheme.SchemeRegistry;
    import org.apache.http.conn.ssl.SSLSocketFactory;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.impl.conn.SingleClientConnManager;
    import org.apache.http.params.HttpParams;
    import java.io.InputStream;
    import java.security.KeyStore;
    
    public class MyHttpClient extends DefaultHttpClient {
      final Context context;
    
      public MyHttpClient(Context context) {
        this.context = context;
      }
    
      public MyHttpClient(Context context2, HttpParams myParams) {
          super(myParams);
          this.context= context2;
    }
    
    @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.mystore);
          try {
            trusted.load(in, "password".toCharArray());
          } finally {
            in.close();
          }
          return new SSLSocketFactory(trusted);
        } catch (Exception e) {
          throw new AssertionError(e);
        }
      }
    }
    

    在构建POST的HTTP Request类中:

    public class HttpRequest {
    MyHttpClient httpClient;
    HttpContext localContext;
    private String ret;
    
    HttpResponse response = null;
    HttpPost httpPost = null;
    HttpGet httpGet = null;
    
    public HttpRequest(Context context){
        HttpParams myParams = new BasicHttpParams();
    
        HttpConnectionParams.setConnectionTimeout(myParams, 10000);
        HttpConnectionParams.setSoTimeout(myParams, 10000);
        httpClient = new MyHttpClient(context, myParams);       
        localContext = new BasicHttpContext();    
    }
    
    public String sendPost(String url, String data, String contentType) {
        ret = null;
    
        httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2109);
    
        httpPost = new HttpPost(url);
        response = null;
    
        StringEntity tmp = null;        
    
        httpPost.setHeader("User-Agent", "SET YOUR USER AGENT STRING HERE");
        httpPost.setHeader("Accept", "text/html,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5");
    
        if (contentType != null) {
            httpPost.setHeader("Content-Type", contentType);
        } else {
            httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
        }
    
        try {
            tmp = new StringEntity(data,"UTF-8");
        } catch (UnsupportedEncodingException e) {
            Log.e("Log", "HttpUtils : UnsupportedEncodingException : "+e);
        }
    
        httpPost.setEntity(tmp);
    
        try {
            response = httpClient.execute(httpPost,localContext);
    
            if (response != null) {
                ret = EntityUtils.toString(response.getEntity());
            }
        } catch (Exception e) {
            Log.e("Log", "HttpUtils: " + e);
        }
    
        return ret;
    }
    }
    

我的POST适用于非https网站。任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:1)

查看错误消息:

  

HttpUtils:javax.net.ssl.SSLException:不受信任的服务器证书

这正是它所说的 - 服务器没有使用可信证书。我敢打赌,如果你试图用Firefox或IE访问同一台服务器,你会得到类似的错误。

答案 1 :(得分:1)

有时,https网址会在android webview中显示空白屏幕。这是因为您必须信任ssl认证,或者您需要覆盖webview客户端中的ssl错误。

以下webview客户端提供访问https网址所需的功能。 这里 shouldOverrideUrlLoading 用于允许在webview中重定向网址, onReceivedSslError 此oneiIgnore SSL证书错误以访问https网址。


Webviewclient:

private class MyWebViewClient extends WebViewClient 
             {
        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            System.out.println("onPageStarted: " + url);
        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView webView, String url) {
            System.out.println("shouldOverrideUrlLoading: " + url); 
            webView.loadUrl(url);
            return true;
        }

        @Override
        public void onPageFinished(WebView webView, String url) {
            System.out.println("onPageFinished: " + url);               

        }

        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler,
                SslError error) {
            handler.proceed(); // Ignore SSL certificate errors
        }   

    }

答案 2 :(得分:0)

使用此类来获取您的HttpClient.And检查它是否有帮助。

包com.android.MyCellFamily.DAHttp;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.HttpVersion;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;

public class MySSLSocketFactory extends SSLSocketFactory {
    SSLContext sslContext = SSLContext.getInstance("TLS");

    public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
        super(truststore);

        TrustManager tm = new X509TrustManager() {
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };

        sslContext.init(null, new TrustManager[] { tm }, null);
    }

    @Override
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
        return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
    }

    @Override
    public Socket createSocket() throws IOException {
        return sslContext.getSocketFactory().createSocket();
    }


public static DefaultHttpClient getNewHttpClient() {
    try {
        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
        trustStore.load(null, null);

        SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
        sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

        HttpParams params = new BasicHttpParams();
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        registry.register(new Scheme("https", sf, 443));

        ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

        return new DefaultHttpClient(ccm, params);
    } catch (Exception e) {
        return new DefaultHttpClient();
    }
}
}