安全专题
自定义控件
- 一分钟实现贴纸功能
- 一分钟实现TextView高亮
- 一分钟实现新手引导页
- 一分钟实现ViewPager卡片
- 一分钟实现轮播图
- 一分钟实现GridView拖拽
- 一分钟实现底部导航栏
- 一分钟实现底部FragmentTabhost
- 一分钟实现多张图片选择
- 一分钟实现仿美拍直播的点赞动画
- 一分钟实现高仿今日头条视频列表
- 一分钟实现购物车加减控件
- 一分钟实现省市县三级联动
- 一分钟实现二维码生成和扫描
- 一分钟实现沉浸式状态栏
- 一分钟实现图片裁剪
- 一分钟实现视频弹幕
- 一分钟实现图片缩放
- 一分钟实现旋转选择器
- 一分钟实现ofo小黄车的引导界面
- 一分钟实现自定义ImageView外貌
- 一分钟实现向左拖拽跳转详情页
- 一分钟实现QQ首页动画特效
- 一分钟实现ViewPager上下滑动
联网
工具
数据库
源码分析相关面试题
Activity相关面试题
- 保存Activity的状态
- 深刻剖析activity启动模式(一)
- 深刻剖析activity启动模式(二)
- 深刻剖析activity启动模式(三)
- Activity Task和Process之间的关系
- 源码分析service开启Activity抛异常?activity不会抛异常
- Activity优雅退出
- onCreate源码分析
Service相关面试题
与XMPP相关面试题
与性能优化相关面试题
与登录相关面试题
与开发相关面试题
- 迭代开发的时候如何向前兼容新旧接口
- 手把手教你如何解决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通信简单图示:
SSL通信详细图示:
当请求使用自签名证书的网站数据时,例如请求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干货程序员
网友评论