Android HTTPS Post-不工作

Android HTTPS Post-不工作,android,post,ssl,https,Android,Post,Ssl,Https,多年来,我一直在努力让它发挥作用——但无论我做什么,我的HTTP*S*帖子总是能产生效果 HttpUtils:javax.net.ssl.SSLException:不受信任的服务器证书 基本上我是这样做的 我成功地从数据库中获取了公共证书(mycert.pem) 服务器 我使用Bouncy Castle成功地从证书创建了密钥库 我未能实现定制的ApacheHttpClient。这是我的 代码: 在构建POST的HTTP请求类中: public class HttpRequest { MyHtt

多年来,我一直在努力让它发挥作用——但无论我做什么,我的HTTP*S*帖子总是能产生效果
HttpUtils:javax.net.ssl.SSLException:不受信任的服务器证书

基本上我是这样做的

  • 我成功地从数据库中获取了公共证书(mycert.pem) 服务器
  • 我使用Bouncy Castle成功地从证书创建了密钥库
  • 我未能实现定制的ApacheHttpClient。这是我的 代码:

    在构建POST的HTTP请求类中:

    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;
    }
    }
    

我的帖子适用于非https网站。如果您有任何帮助,我们将不胜感激。

请查看错误消息:

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


这意味着服务器没有使用可信证书。我敢打赌,如果您尝试使用Firefox或IE访问同一台服务器,您会遇到类似的错误。

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

软件包com.android.mycellfamine.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();
    }
}
}

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

以下webview客户端提供访问https url所需的函数。 此处,shouldOverrideUrlLoading用于允许webview中的重定向url,OnReceivedSlerror此oneiIgnore SSL证书错误访问https url


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
        }   

    }

Android制造商信任的证书很少(可能是普通证书的一半?),当浏览器未运行时(如在webview或原始问题中),不会出现弹出问题,要求最终用户接受不受信任的证书。因此,您必须在您自己的代码中修复此问题,如下面两个示例中所示,这样才能正常工作。仅使用上面示例中留下的onReceivedSlerRor(…)方法,它就可以很好地传递cookies和所有内容。这救了我一天,非常感谢!
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
        }   

    }