Android面试题-Java安全专题七

Android程序员面试宝典

安全专题

  • Java安全专题一
  • Java安全专题二
  • Java安全专题三
  • Java安全专题四
  • Java安全专题五
  • Java安全专题六
  • Java安全专题七

自定义控件

  • 一分钟实现贴纸功能
  • 一分钟实现TextView高亮
  • 一分钟实现新手引导页
  • 一分钟实现ViewPager卡片
  • 一分钟实现轮播图
  • 一分钟实现GridView拖拽
  • 一分钟实现底部导航栏
  • 一分钟实现底部FragmentTabhost
  • 一分钟实现多张图片选择
  • 一分钟实现仿美拍直播的点赞动画
  • 一分钟实现高仿今日头条视频列表
  • 一分钟实现购物车加减控件
  • 一分钟实现省市县三级联动
  • 一分钟实现二维码生成和扫描
  • 一分钟实现沉浸式状态栏
  • 一分钟实现图片裁剪
  • 一分钟实现视频弹幕
  • 一分钟实现图片缩放
  • 一分钟实现旋转选择器
  • 一分钟实现ofo小黄车的引导界面
  • 一分钟实现自定义ImageView外貌
  • 一分钟实现向左拖拽跳转详情页
  • 一分钟实现QQ首页动画特效
  • 一分钟实现ViewPager上下滑动

联网

  • 一分钟学会Retrofit并且进行实战
  • 一分钟实现OkHttp3

工具

  • 一分钟实现RecyclerView
  • 一分钟实现H5和Android通信
  • 一分钟实现pinyin4j
  • 一分钟实现分析内存泄漏

数据库

  • 一分钟实现LitePal数据库
  • 一分钟实现ormlite数据库
  • 一分钟实现GreenDao数据库

源码分析相关面试题

  • Volley源码分析
  • 注解框架实现原理
  • okhttp3.0源码分析
  • onSaveInstanceState源码分析
  • 静默安装和源码编译

Activity相关面试题

  • 保存Activity的状态
  • 深刻剖析activity启动模式(一)
  • 深刻剖析activity启动模式(二)
  • 深刻剖析activity启动模式(三)
  • Activity Task和Process之间的关系
  • 源码分析service开启Activity抛异常?activity不会抛异常
  • Activity优雅退出
  • onCreate源码分析

Service相关面试题

  • IntentService源码分析
  • Service是否在main thread中执行, service里面是否能执行耗时的操作?
  • Service不死之身

与XMPP相关面试题

  • XMPP协议优缺点
  • 极光消息推送原理

与性能优化相关面试题

  • 内存泄漏和内存溢出区别
  • UI优化和线程池实现原理
  • 代码优化
  • 内存性能分析
  • 内存泄漏检测
  • App启动优化
  • 与IPC机制相关面试题

与登录相关面试题

  • oauth认证协议原理
  • token产生的意义
  • 微信扫一扫实现原理

与开发相关面试题

  • 迭代开发的时候如何向前兼容新旧接口
  • 手把手教你如何解决as jar包冲突
  • context的原理分析
  • 解决ViewPager.setCurrentItem中间很多页面切换方案
  • 字体适配
  • 软键盘适配
  • 机型适配,例如三星、小米、华为、魅族等
  • CardView 设置水波纹效果

与人事相关面试题

  • 人事面试宝典

1.7 Https编程

1.7.1 介绍

SSL(Secure Sockets Layer 安全套接层),为网景公司(Netscape)所研发,用以保障在Internet上数据传输之安全,利用数据加密(Encryption)技术,可确保数据在网络上之传输过程中不会被截取及窃听。一般通用之规格为40 bit之安全标准,美国则已推出128 bit之更高安全标准,但限制出境。只要3.0版本以上之I.E.或Netscape浏览器即可支持SSL。

TLS(Transport Layer Security传输层安全),用于在两个通信应用程序之间提供保密性和数据完整性。TLS是SSL的标准化后的产物,有1.0 ,1.1 ,1.2三个版本,默认使用1.0。TLS1.0和SSL3.0几乎没有区别 ,事实上我们现在用的都是TLS,但因为历史上习惯了SSL这个称呼。

SSL通信简单图示:

Android面试题-Java安全专题七_第1张图片

SSL通信详细图示:

Android面试题-Java安全专题七_第2张图片

当请求使用自签名证书的网站数据时,例如请求12306的客运服务页面:https://kyfw.12306.cn/otn/,
则会报下面的错误,原因是客户端的根认证机构不能识别该证书
错误信息:unable to find valid certification path to requested target

1.7.2 解决方案1

一个证书可不可信,是由TrustManager决定的,所以我们只需要自定义一个什么都不做的TrustManager即可,服务器出示的所有证书都不做校验,一律放行。

public static void main(String[] args) throws Exception {
    //协议传输层安全TLS(transport layer secure)
    SSLContext sslContext = SSLContext.getInstance("TLS");
    //创建信任管理器(TrustManager负责校验证书是否可信)
    TrustManager[] tm = new TrustManager[]{new EmptyX509TrustManager()};
    /使用自定义的信任管理器初始化SSL上下文对象
    sslContext.init(null, tm, null);
      //设置全局的SSLSocketFactory工厂(对所有ssl链接都产生影响)
      HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());         
    //URL url = new URL("https://www.baidu.com");
    URL url = new URL("https://kyfw.12306.cn/otn/");
    HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
    InputStream in = conn.getInputStream();
    System.out.println(Util.inputstream2String(in));
    }       
    /**
     * 自定义一个什么都不做的信任管理器,所有证书都不做校验,一律放行
    */
    private static class EmptyX509TrustManager implements X509TrustManager{
    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType)
            throws CertificateException {
    }
    @Override
    public void checkServerTrusted(X509Certificate[] chain, String authType)
                    throws CertificateException {
    }
    @Override
    public X509Certificate[] getAcceptedIssuers() {return null;
    }           
}

1.7.3 解决方案2

12306服务器出示的证书是中铁集团SRCA给他颁发的,所以SRCA的证书是能够识别12306的证书的,所以只需要把SRCA证书导入系统的KeyStore里,之后交给TrustManagerFactory 进行初始化,则可把SRCA添加至根证书认证机构,之后校验的时候,SRCA对12306证书校验时就能通过认证。
这种解决方案有两种使用方式:一是直接使用SRCA.cer文件,二是使用改文件的RFC格式数据,将其写在代码里。

//12306证书的RFC格式(注意要记得手动添加两个换行符)
private static final String CERT_12306_RFC = "-----BEGIN CERTIFICATE-----\n"
+ "MIICmjCCAgOgAwIBAgIIbyZr5/jKH6QwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ04xKTAn"
+ "BgNVBAoTIFNpbm9yYWlsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRTUkNBMB4X"
+ "DTA5MDUyNTA2NTYwMFoXDTI5MDUyMDA2NTYwMFowRzELMAkGA1UEBhMCQ04xKTAnBgNVBAoTIFNp"
+ "bm9yYWlsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRTUkNBMIGfMA0GCSqGSIb3"
+ "DQEBAQUAA4GNADCBiQKBgQDMpbNeb34p0GvLkZ6t72/OOba4mX2K/eZRWFfnuk8e5jKDH+9BgCb2"
+ "9bSotqPqTbxXWPxIOz8EjyUO3bfR5pQ8ovNTOlks2rS5BdMhoi4sUjCKi5ELiqtyww/XgY5iFqv6"
+ "D4Pw9QvOUcdRVSbPWo1DwMmH75It6pk/rARIFHEjWwIDAQABo4GOMIGLMB8GA1UdIwQYMBaAFHle"
+ "tne34lKDQ+3HUYhMY4UsAENYMAwGA1UdEwQFMAMBAf8wLgYDVR0fBCcwJTAjoCGgH4YdaHR0cDov"
+ "LzE5Mi4xNjguOS4xNDkvY3JsMS5jcmwwCwYDVR0PBAQDAgH+MB0GA1UdDgQWBBR5XrZ3t+JSg0Pt"
+ "x1GITGOFLABDWDANBgkqhkiG9w0BAQUFAAOBgQDGrAm2U/of1LbOnG2bnnQtgcVaBXiVJF8LKPaV"
+ "23XQ96HU8xfgSZMJS6U00WHAI7zp0q208RSUft9wDq9ee///VOhzR6Tebg9QfyPSohkBrhXQenvQ"
+ "og555S+C3eJAAVeNCTeMS3N/M5hzBRJAoffn3qoYdAO1Q8bTguOi+2849A=="
+ "-----END CERTIFICATE-----\n";
public static void main(String[] args) throws Exception {
    // 使用传输层安全协议TLS(transport layer secure)
    SSLContext sslContext = SSLContext.getInstance("TLS");
    //使用SRCA.cer文件的形式
    //FileInputStream certInputStream = new FileInputStream(new File("srca.cer"));
    //也可以通过RFC字符串的形式使用证书
    ByteArrayInputStream certInputStream = new ByteArrayInputStream(CERT_12306_RFC.getBytes());
    // 初始化keyStore,用来导入证书
    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    //参数null表示使用系统默认keystore,也可使用其他keystore(需事先将srca.cer证书导入keystore里)
    keyStore.load(null);
    //通过流创建一个证书
    Certificate certificate = CertificateFactory.getInstance("X.509")
                    .generateCertificate(certInputStream);
    // 把srca.cer这个证书导入到KeyStore里,别名叫做srca
    keyStore.setCertificateEntry("srca", certificate);
    // 设置使用keyStore去进行证书校验
    TrustManagerFactory trustManagerFactory = TrustManagerFactory
                .getInstance(TrustManagerFactory.getDefaultAlgorithm());
    trustManagerFactory.init(keyStore);
    //用我们设定好的TrustManager去做ssl通信协议校验,即证书校验
    sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
    HttpsURLConnection.setDefaultSSLSocketFactory(sslContext
                    .getSocketFactory());
    URL url = new URL("https://kyfw.12306.cn/otn/");
    HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
    InputStream in = conn.getInputStream();
    System.out.println(Util.inputstream2String(in));
}

1.7.4 Android里的https请求 :

把scra.cer文件考到assets或raw目录下,或者直接使用证书的RFC格式,接下来的做法和java工程代码一样

  • 欢迎关注微信公众号、长期为您推荐优秀博文、开源项目、视频

  • 微信公众号名称:Android干货程序员

你可能感兴趣的:(Android面试题-Java安全专题七)