日常开发——Android请求自定义证书的https

有时候为了app的数据安全,开发者会考虑使用https来进行数据传输。在安卓上,原生的HttpsURLConnection和WebView只支持那些得到安卓系统承认的证书的站点。如果请求那些使用未通过系统认证的证书的站点,则系统会报错。对于个人开发者来说,申请正规的证书性价比不高,每年都需要不少的费用,而且开发阶段会被申请流程阻塞,所以使用自定义的证书就好。现在的问题是怎么让app绕过系统的证书认证,从而接受自定义的证书。


HttpsURLConnection

该例程是参考别人的代码修改而来的,下载一个线程里面。可以验证特定的证书。该证书应保存一个副本在app本地上(assets),保存为.crt格式。至于怎样生成自定义的证书,请Google。其中一个内部类实现了HostnameVerifier接口,可以验证特定主机名,以匹配hostname和证书。这里的实现是不对主机名进行验证,默认接受持有该证书所有的主机。

 @Override
    public void run(){
        HttpsURLConnection urlConnection = null;
        try {
            URL url = new URL(Constant.update_url);
            //https

            // Load CAs from an InputStream
            // (could be from a resource or ByteArrayInputStream or ...)
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            InputStream in = context.getAssets().open("ca.crt");
            Certificate ca = cf.generateCertificate(in);

            // Create a KeyStore containing our trusted CAsString keyStoreType = KeyStore.getDefaultType();
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null, null);
            keyStore.setCertificateEntry("ca", ca);

            // Create a TrustManager that trusts the CAs in our KeyStore
            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(keyStore);

            // Create an SSLContext that uses our TrustManager
            SSLContext context = SSLContext.getInstance("TLS");
            context.init(null, tmf.getTrustManagers(), null);

            HttpsURLConnection.setDefaultHostnameVerifier(new MyHostnameVerifier());

            urlConnection = (HttpsURLConnection)url.openConnection();

            urlConnection.setSSLSocketFactory(context.getSocketFactory());
            urlConnection.setRequestMethod("GET");
            urlConnection.connect();
            String data = ReceiveRequestData.responseData(urlConnection);

        }catch (Exception e){
            e.printStackTrace();
        }finally {
        }
    }

    private class MyHostnameVerifier implements HostnameVerifier {

        @Override
        public boolean verify(String hostname, SSLSession session) {
            // TODO Auto-generated method stub
            return true;
        }
    }

WebView

如果需要验证特定的证书,WebView上没有很好的办法。看了网上的解决方案,是说找到WebViewClient的隐藏方法并重写,但因为是隐藏方法,需要找到编译包,工程量较大。如果是开发阶段的话,不妨使用接受所有证书的方法,代码也比较简单。

</pre>新建一个类并继承WebViewClient,重写里面的onReceivedSslError方法:</p><p><pre name="code" class="java">private class MyWebViewClient extends WebViewClient{
        public MyWebViewClient(WebView webView) {
            super(webView);
        }

        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error){
            //handler.cancel(); // Android默认的处理方式
            handler.proceed();  // 接受所有网站的证书
            //handleMessage(Message msg); // 进行其他处理
        }
    }
然后为WebView对象设置Client

mainView.setWebViewClient(new MyWebViewClient(mainView));






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值