Android 网络安全之https

简单说一下 http 和https 的区别 http是应用层协议 而https是http 的升级版 是网络安全大趋势之下的产物 在现有条件下 常规的http已经无法保证数据和平台的安全,所以https 已成大势 目前的http 通过一些工具是可以抓取到数据的 例如Fiddler ,charles 就能轻易抓取http的请求数据 而https 则可以轻松避免这种抓取数据的方式
http 请求是通过 http + tcp 进行的应用传输的 而https 则是在http 和 tcp 之间加了一层安全验证也就是 SSL/TLS的验证 数据证书验证是使用CA证书(数据证书颁发机构办法的证书)进行密码校验 通过验证才能进行网络请求

下面说一下android 的https (以okhttp为例)

先说下本人的策略 使用二级缓存的方法进行证书加载 现在很多朋友大都是以硬编码的方式或内置证书的方式加载 本人觉得这种方式是不安全的 第一不安全是因为有意破坏者可以通过反编译 或者 破解获取你的证书 第二 ca证书是由时间限制的 如果时间到期 再去更换证书 而你只能通过强制更新才能让用户进行使用 这个会给用户很不好的体验

我的策略是 内置加缓存的方式加载证书 首先缓存是需要权限的 若用户没有授权 则终端无法缓存 用户也就无法正常使用 此时我使用内置的 如果客户授权了读写权限 我就是用缓存的 以此避免证书过期问题

证书验证 也有两种方式 第一 单项验证(弱验证)(服务器验证客户端携带的证书是否有效)第二 双向验证(强验证) 客户端验证
服务端握手时返回的公钥信息进行host验证 服务器在验证客户端的数字签名是否正确 一般双向验证是 浏览器金融类app等使用的较多 也是非常安全的一种方式 ; 我使用的是第一种单项验证 因为我的host是我自己设定好的 所以我没有进行host 验证

public class SSLUtil {

    /**
     * 获取SSLSocketFactory
     *
     * @param certificates 证书流文件
     * @return
     */
    public static SSLSocketFactory getSSLSocketFactory(InputStream... certificates) {

        try {
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null);
            int index = 0;
            for (InputStream certificate : certificates) {
                String certificateAlias = Integer.toString(index++);
                keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));
                try {
                    if (certificate != null)
                        certificate.close();
                } catch (IOException e) {
                }
            }
            SSLContext sslContext = SSLContext.getInstance("TLS");
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(keyStore);
            sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
            return sslContext.getSocketFactory();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

返回SSLSocketFactory 

// 网络请求方法
OkHttpClient.Builder okBuilder = new OkHttpClient.Builder().addInterceptor(interceptor)
               .writeTimeout(BaseConstant.NET_WRITE_TIME_OUT, TimeUnit.SECONDS)
               .readTimeout(BaseConstant.NET_READ_TIME_OUT, TimeUnit.SECONDS)
               .connectTimeout(BaseConstant.NET_REQUEST_TIME_OUT, TimeUnit.SECONDS)
               .retryOnConnectionFailure(true)
               .addInterceptor(new ErrorStatuInterceptor())
               .addInterceptor(new PrintLogInterceptor());
       if (CA.getCAFile()!=null){
           if (SSLUtil.getSSLSocketFactory(CA.getCAByte()) != null){
               okBuilder.hostnameVerifier(new HostnameVerifier() {
                   @Override
                   public boolean verify(String s, SSLSession sslSession) {
                       return true;
                   }
                 }).sslSocketFactory(SSLUtil.getSSLSocketFactory(CA.getCAByte()));
           }
       }else {
           if (SSLUtil.getSSLSocketFactory(CA.getCAByte()) != null){
               try {
                   okBuilder.hostnameVerifier(new HostnameVerifier() {
                       @Override
                       public boolean verify(String s, SSLSession sslSession) {
                           return true;
                       }
                   }).sslSocketFactory(SSLUtil.getSSLSocketFactory(UiUtils.getContext().getAssets().open("nade.cer")));
               } catch (IOException e) {
                   e.printStackTrace();
               }
               //  }).sslSocketFactory(SSLUtil.getSSLSocketFactory(CA.getCAByte()));
           }

       }

// 此方法用于验证host 返回true 是不验证

 okBuilder.hostnameVerifier(new HostnameVerifier() {
                   @Override
                   public boolean verify(String s, SSLSession sslSession) {
                       return true;
                   }

这个可以可以根据需要进行验证

好了 不多说 到此结束 有需要可以私信我

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1,从素材到线稿,将素材概括重组一下,提炼出哪些重点刻画,哪些虚化。 将远山变虚,重点刻画近景的人物。因为画...
    步摇阅读 852评论 0 2
  • 使用dispatch_once的注意事项: 此函数接收类型为dispatch_once_t的特殊参数,还有一个块参...
    皆为序幕_阅读 318评论 0 0
  • 一直以来,我都很喜欢一句话——我哒哒的马蹄是个美丽的错误,我不是归人,我只是个过客。 是啊,我不愿把路过我人生的人...
    今心何兮阅读 591评论 0 2