Android的HTTPS错误不被信任的服务器证书 [英] Android Https error Not trusted server certificate

查看:680
本文介绍了Android的HTTPS错误不被信任的服务器证书的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的情况,当我在模拟器上运行PROGRAMM - 它的工作correktly。 但是,当我安装apk文件到手机 - 有错误不被信任的服务器证书。 这是什么问题?

有我的AsyncTask的用于发送响应于所述服务器code:

 公共抽象类BaseAsyncWorker扩展的AsyncTask<字符串,太虚,字符串> {
公共静态最终字符串=BaseAsyncWorker;
私人字符串URL;
私人字符串的结果;
最后上下文的背景下;

公共BaseAsyncWorker(字符串URL,上下文语境){
    this.URL =网址;
    this.context =背景;
}
//之前
@覆盖
在preExecute保护抽象无效();

//背景
@覆盖
保护字符串doInBackground(字符串...对象){
    对于(字符串OBJ:对象){
        Log.d(AS,obj.toString());
        Log.d(AS,开始的背景);
        Logger.appendLog(开始的反应......);
        尝试{


            的HostnameVerifier的HostnameVerifier = SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;

            DefaultHttpClient客户端=新DefaultHttpClient();

            SchemeRegistry注册表=新SchemeRegistry();
            SSLSocketFactory的的SocketFactory = SSLSocketFactory.getSocketFactory();
            socketFactory.setHostnameVerifier((X509HostnameVerifier)的HostnameVerifier);
            registry.register(新计划(HTTP,PlainSocketFactory.getSocketFactory(),80));
            registry.register(新计划(https开头,的SocketFactory,443));
            SingleClientConnManager mngr =新SingleClientConnManager(client.getParams()
                                                                        注册);
            // trustEveryone();
            DefaultHttpClient的HttpClient =新DefaultHttpClient(mngr,client.getParams());

            // MMGHttpClient的HttpClient =新MMGHttpClient(上下文);
            //httpClient.getParams().setParameter(CoreProtocolPNames.USER_AGENT,MyMobiGift有限公司安卓);
            //HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);

            HttpPost httpPost =新HttpPost(URL);

            StringEntity SE =新StringEntity(OBJ);
            httpPost.setEntity(SE);
            httpPost.setHeader(接受,应用/ JSON);
            httpPost.setHeader(内容型,应用/ JSON);



            HTT presponse响应=(HTT presponse)httpClient.execute(httpPost);
            状态行状态= response.getStatusLine();
            如果((status.getStatus code())== 200){
                HttpEntity实体= response.getEntity();
                如果(实体!= NULL){
                    InputStream的河道= entity.getContent();
                    结果= convertStreamToString(河道);
                    instream.close();
                    Logger.appendLog(末日回响与结果:+结果);
                }其他{
                    结果= NULL;
                    Logger.appendLog(最终回应无果而终);
                }
            }
        }赶上(ClientProtocolException E){Logger.appendLog(ClientProtocolException在+ e.getMessage());}
        赶上(IOException异常E){Logger.appendLog(IOException异常的+ e.getMessage());}

    }
    返回结果;
}
 

解决方案

这是帮我建立基于SSL的正常工作的HTTP通讯。

http://blog.antoine.li/2010 / 10/22 / Android的信任-SSL-证书/

如果您希望客户端(Android设备)真的(不要盲目)信任主机,公证书需要加载到设备的密钥库,否则设备将不说话服务器

您将使用.crt文件,但与Android密钥库使用,你需要它转换为BKS。我做如下:

  //从内存中读取.crt文件
的InputStream inStream中= ctx.openFileInput(cetificate.crt);

//为InputStream inStream中= ctx.getAssets()开(wm_loaner.cer)。
如果(inStream中!= NULL)
{
    密钥库证书= CertUtils.ConvertCerToBKS(inStream中,MyAlias​​,密码.toCharArray());
    inStream.close();
}

公共静态密钥库ConvertCerToBKS(InputStream的cerStream,字符串别名的char []密码)
{
    密钥库的keyStore = NULL;
    尝试
    {
        的keyStore = KeyStore.getInstance(BKS,BC);
        CertificateFactory工厂= CertificateFactory.getInstance(X.509,BC);
        证书= factory.generateCertificate(cerStream);
        keyStore.load(空,密码);
        keyStore.setCertificateEntry(别名,证书);
    }
    抓住 ....
    {
    }
    返回的keyStore;
}
 

在证书转换并加载到你可以建立连接的密钥库

In my situation when I run programm on emulator - its work correktly. But when I install apk to phone - have error Not trusted server certificate. What is the problem?

there is a code of my AsyncTask for sending response to the server:

public abstract class BaseAsyncWorker extends AsyncTask<String, Void, String>{
public static final String AS = "BaseAsyncWorker";
private  String URL;
private String result;
final Context context;

public BaseAsyncWorker(String url,Context context){
    this.URL = url; 
    this.context = context;
}
//before
@Override
protected abstract void onPreExecute();

//background
@Override
protected  String doInBackground(String... objects) {
    for (String obj : objects) {
        Log.d(AS,obj.toString() );
        Log.d(AS,"beginning background" );
        Logger.appendLog("Start response...");
        try{


            HostnameVerifier hostnameVerifier = SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;

            DefaultHttpClient client = new DefaultHttpClient();

            SchemeRegistry registry = new SchemeRegistry();
            SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
            socketFactory.setHostnameVerifier((X509HostnameVerifier)hostnameVerifier);
            registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
            registry.register(new Scheme("https", socketFactory,443));
            SingleClientConnManager mngr = new SingleClientConnManager(client.getParams(),
                                                                        registry);
            //trustEveryone();
            DefaultHttpClient httpClient = new DefaultHttpClient(mngr,client.getParams());

            //MMGHttpClient httpClient = new MMGHttpClient(context);
            //httpClient.getParams().setParameter(CoreProtocolPNames.USER_AGENT, "MyMobiGift Ltd. Android");
            //HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);

            HttpPost httpPost = new HttpPost(URL); 

            StringEntity se = new StringEntity(obj);
            httpPost.setEntity(se);
            httpPost.setHeader("Accept", "application/json");
            httpPost.setHeader("Content-type", "application/json");



            HttpResponse response = (HttpResponse)httpClient.execute(httpPost);
            StatusLine status = response.getStatusLine();
            if((status.getStatusCode())==200){
                HttpEntity entity = response.getEntity();
                if(entity!=null){
                    InputStream instream = entity.getContent();
                    result= convertStreamToString(instream);
                    instream.close();
                    Logger.appendLog("End response with result: "+result);
                }else{
                    result=null;
                    Logger.appendLog("End response without result");
                }
            }
        }catch (ClientProtocolException e) {Logger.appendLog("ClientProtocolException at"+e.getMessage());}
        catch (IOException e) {Logger.appendLog("IOException at" + e.getMessage());}

    }   
    return result;  
}

解决方案

This is what helped me to build a proper working http communication over ssl.

http://blog.antoine.li/2010/10/22/android-trusting-ssl-certificates/

If you want client (android device) really (not blindly) trusts host, public certificate needs to be loaded to device's KeyStore, otherwise device won't talk to the server

You will use .crt file but to use with Android KeyStore you need it to be converted to "bks". I do following:

// read .crt file from memory
InputStream inStream = ctx.openFileInput("cetificate.crt");

//InputStream inStream = ctx.getAssets().open("wm_loaner.cer");
if(inStream != null)
{
    KeyStore cert = CertUtils.ConvertCerToBKS(inStream, "MyAlias", "password".toCharArray());
    inStream.close();
}

public static KeyStore ConvertCerToBKS(InputStream cerStream, String alias, char [] password)
{
    KeyStore keyStore = null;
    try
    {
        keyStore = KeyStore.getInstance("BKS", "BC");
        CertificateFactory factory = CertificateFactory.getInstance("X.509", "BC");
        Certificate certificate = factory.generateCertificate(cerStream);
        keyStore.load(null, password);
        keyStore.setCertificateEntry(alias, certificate);
    }
    catch ....
    {
    }
    return keyStore;                                    
}

After certificate was converted and loaded to the KeyStore you can establish a connection

这篇关于Android的HTTPS错误不被信任的服务器证书的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆