HTTP2.0 HTTPS学习
来源:互联网 发布:十代思域18寸轮毂数据 编辑:程序博客网 时间:2024/06/05 22:32
HTTP2.0 HTTPS学习
消除或减少不必要的网络延迟,将需要传输的数据压缩
1、HTTP2.0与 HTTP/1.1 完全语义兼容的基础上,进一步减少了网络延迟
2、HTTP2.0多路复用:
允许同时通过单一的 HTTP/2连接发起多重的请求-响应消息(即可在同一个TCP连接上双向传输数据,从而实现多流并行而不依赖多个TCP连接,实际上HTTP/2 通信都在一个连接上完成,这个连接可以承载任意数量的双向数据流)HTTP/1.1、HTTP1.0 协议中,浏览器针对同一域名的请求限制阻塞问题(浏览器客户端在同一时间,针对同一域名(浏览器或者客户端是根据domain(域名)来建立连接)的请求有一定数量限制,超过限制数目的请求会被阻塞)
多路复用即连接共享:
一个request对应一个stream并分配一个id,一个连接上可以有多个stream,每个stream的frame可以随机的混杂在一起,接收方可以根据stream id将frame再归属到各自不同的request里面。
优先级和请求依赖的机制配合才能解决关键请求被阻塞的问题 — http2.0里的每个stream都可以设置又优先级(Priority)和依赖(Dependency)。优先级高的stream会被server优先处理和返回给客户端,stream还可以依赖其它的sub streams。优先级和依赖都是可以动态调整的。
(原http1.x协议头里可以设置Connection:Keep-Alive。在header里设置Keep-Alive可以在一定时间内复用连接)
HTTP 性能优化:
HTTP/2 通过让所有数据流共用同一个连接,可以更有效地使用 TCP 连接
减少服务端的链接压力,内存占用更少,连接吞吐量更大,连接的减少使网络拥塞状况得以改善,同时慢启动时间的减少, 使拥塞和丢包恢复速度更快
3、二进制分帧
此为HTTP2.0突破 HTTP1.1 的性能限制,改进传输性能,实现低延迟和高吞吐量的关键
二进制分帧层处于应用层(HTTP/2)和传输层(TCP or UDP)之间
二进制分帧层中,HTTP/2会将所有传输的信息转换为更小的消息和帧(frame),
并对它们采用二进制格式的编码,其中HTTP1.x的首部信息被封装为HEADER frame,而相应的Request Body则封装到DATA frame里面,这也是HTTP2.0兼容HTTP1.x的关键
4、首部压缩
HTTP/1.1并不支持HTTP首部压缩,SPDY使用DEFLATE算法,而HTTP/2使用专门为首部压缩而设计的HPACK算法
5、基于HTTPS的加密协议传输
HTTP2.0使用了tls的拓展ALPN来做协议升级,可通过黑名单机制禁用了不安全的加密算法来加强安全性能,从而大大提高了传输数据的可靠性,同时HTTP2.0也支持明文HTTP传输,而SPDY强制使用HTTPS
6、服务端推送
一种在客户端请求之前发送数据的机制。
服务器推送:服务器可以对客户端的一个请求发送多个响应,
可以缓存!也让在遵循同源的情况下,不同页面之间可以共享缓存资源成为可能。
Android平台http2.0:
它只在新系统下支持,android系统webview从android4.4(KitKat)才改成基于chrome内核的(chrome内核的webview才能支持spdy和http2.0)。
okhttp是同时支持spdy和http2.0,如果使用ALPN,okhttp要求android系统5.0+(实际上,android4.4上就有了ALPN的实现,不过有bug,知道5.0才正式修复)
//数字签名技术实现了身份认证与数据完整性保证: 消息摘要与非对称加密实现
//消息摘要算法保证了数据的完整性
HTTPS:
HTTPS是HTTP over SSL/TLS,HTTP是应用层协议,TCP是传输层协议,在应用层和传输层之间,增加了一个安全套接层SSL/TLS
SSL/TLS层负责客户端和服务器之间的加解密算法协商、密钥交换、通信连接的建立
SSL(Secure Sockets Layer 安全套接层)
TLS(Transport Layer Security 传输层安全),TLS 是SSL 的标准化后的产物
X509证书链,CA根证书,RA中间机构
Https的工作原理;
1、客户端向服务器发起Https请求;
2、服务器响应并下发证书,证书包含有公钥、证书颁发机构、过期时间、对称加密算法种类等信息;
3、客户端接收到证书后,解析证书信息验证是否合法;
4、证书合法客户端解析对称加密算法种类,并生成对应的密钥(对称加密)通过公钥加密给服务器;
5、后面服务器与客户端通讯就采用对称加密进行加解密,密钥只有客户端与服务器知道,只要加密算法够安全,数据就足够安全;
Https和Http的区别:
1、HTTP 的URL 以http:// 开头,而HTTPS 的URL 以https://
HTTP协议运行在TCP之上,,HTTPS运行在SSL/TLS之上,SSL/TLS运行在TCP之上
2、HTTP 传输的内容都是明文、不安全,而HTTPS 对传输的数据进行加密、相对安全
3、HTTP 无需证书,而HTTPS 需要CA机构wosign的颁发的SSL证书
5、HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443
android https使用:
SSLContext — 负责证书管理和信任管理器,Https可以有证书也可以没有证书
HostnameVerifier — 主机名称校验
使用HttpsURLConnection进行HTTPS通信
1、TrustManger的checkServerTrusted()
2、对服务器证书域名进行强校验或者真正实现HostnameVerifier的verify()方法
使用OKHttp3.0进行HTTPS通信
public final class HTTPSUtils { private OkHttpClient client; public Context mContext; /初始化HTTPS,添加信任证书 public HTTPSUtils(Context context) { mContext = context; X509TrustManager trustManager; SSLSocketFactory sslSocketFactory; final InputStream inputStream; try { inputStream = mContext.getAssets().open("srca.cer"); // 得到证书的输入流 try { trustManager = trustManagerForCertificates(inputStream);//以流的方式读入证书 SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, new TrustManager[]{trustManager}, null); sslSocketFactory = sslContext.getSocketFactory(); } catch (GeneralSecurityException e) { throw new RuntimeException(e); } client = new OkHttpClient.Builder() .sslSocketFactory(sslSocketFactory, trustManager) //https方式 .build(); } catch (IOException e) { e.printStackTrace(); } } public void run() throws Exception { Request request = new Request.Builder() .url("https://kyfw.12306.cn/otn/") .build(); //okhttp 异步执行request请求 client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { System.out.println(response.body().string()); } }); } //以流的方式添加信任证书 private X509TrustManager trustManagerForCertificates(InputStream in) throws GeneralSecurityException { // 证书工厂 CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(in); if (certificates.isEmpty()) { throw new IllegalArgumentException("expected non-empty set of trusted certificates"); } // Put the certificates a key store. char[] password = "password".toCharArray(); // Any password will work. // 密钥库 KeyStore keyStore = newEmptyKeyStore(password); int index = 0; for (Certificate certificate : certificates) { String certificateAlias = Integer.toString(index++); keyStore.setCertificateEntry(certificateAlias, certificate); } // Use it to build an X509 trust manager. // 密钥管理器 KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance( KeyManagerFactory.getDefaultAlgorithm()); keyManagerFactory.init(keyStore, password); // 信任管理器 TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(keyStore); //加载密钥库到信任管理器 TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) { throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers)); } return (X509TrustManager) trustManagers[0]; } // 生成密钥库 private KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException { try { KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); // 这里添加自定义的密码,默认 InputStream in = null; // 密码文件或字符串, 'null' creates an empty key store. keyStore.load(in, password); return keyStore; } catch (IOException e) { throw new AssertionError(e); } } } 有安全证书的SSLContext:public static SSLContext getSSLContext() { // 生成SSLContext对象 SSLContext sslContext = SSLContext.getInstance("TLS"); // 从assets中加载证书 InputStream inStream = Application.getInstance().getAssets().open("srca.cer"); // 证书工厂 CertificateFactory cerFactory = CertificateFactory.getInstance("X.509"); Certificate cer = cerFactory.generateCertificate(inStream); // 密钥库 KeyStore kStore = KeyStore.getInstance("PKCS12"); kStore.load(null, null); kStore.setCertificateEntry("trust", cer);// 加载证书到密钥库中 // 密钥管理器 KeyManagerFactory keyFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); keyFactory.init(kStore, null);// 加载密钥库到管理器 // 信任管理器 TrustManagerFactory tFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tFactory.init(kStore);// 加载密钥库到信任管理器 // 初始化 sslContext.init(keyFactory.getKeyManagers(), tFactory.getTrustManagers(), new SecureRandom()); return sslContext;}//没有安全证书的SSLContext://需要两个对象://SSLContext + HostnameVerifier(主机名称校验)public static SSLContext getSLLContext() { SSLContext sslContext = null; try { sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, new TrustManager[]{new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) {} @Override public void checkServerTrusted(X509Certificate[] chain, String authType) {} @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } }}, new SecureRandom()); } catch (Exception e) { e.printStackTrace(); } return sslContext;}private static HostnameVerifier hostnameVerifier = new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; }};//URL url = new URL("http://blog.csdn.net/yanzhenjie1003");HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();urlConnection.setRequestMethod("GET");// 1、设置SSLSocketFoactory 需要安全证书if (urlConnection instanceof HttpsURLConnection) { // 是Https请求 SSLContext sslContext = SSLContextUtil.getSSLContext(); // 有安全证书的SSLContext if (sslContext != null) { SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); ((HttpsURLConnection) urlConnection).setSSLSocketFactory(sslSocketFactory); }}// 2、设置SSLSocketFoactory 不需要安全证书if (urlConnection instanceof HttpsURLConnection) { // 是Https请求 SSLContext sslContext = SSLContextUtil.getSSLContext(); //没有安全证书的SSLContext: if (sslContext != null) { SSLSocketFactory sslSocketFactory = sslContext.getSLLContextNoCertificate(); //没有证书 ((HttpsURLConnection) urlConnection).setSSLSocketFactory(sslSocketFactory); ((HttpsURLConnection) urlConnection).setHostnameVerifier(SSLContextUtil.hostnameVerifier); }}// 设置属性urlConnection.setConnectTimeout(8 * 1000);urlConnection.setReadTimeout(8 * 1000);int responseCode = urlConnection.getResponseCode();if (responseCode == 200) { // 请求成功 InputStream inputStream = urlConnection.getInputStream(); // 读取结果,发送到主线程 ... inputStream.close();}urlConnection.disconnect();
- HTTP2.0 HTTPS学习
- HTTP、HTTPS、SPDY、HTTP2.0
- HTTP,HTTP2.0,SPDY,HTTPS看这篇就够了
- HTTP,HTTP2.0,SPDY,HTTPS区别
- http和https和http2.0
- HTTP,HTTP2.0,SPDY,HTTPS看这篇就够了
- HTTP1.X HTTPS SSL HTTP2.0
- nginx+http2+https
- nginx https http2
- Http2.2实现https
- 关于 iOS HTTP2.0 的学习实践
- HTTPS 与 HTTP2 协议分析
- HTTPS 与 HTTP2 协议分析
- HTTPS 与 HTTP2 协议分析
- Nginx上部署HTTPS + HTTP2
- springboot+undertow+http+https+http2
- Http2.0
- HTTP2.0
- IGN评史上最佳100 RPG
- 2017/5/9
- redis 安装以及phpredis拓展安装
- ajax访问后台,数据放到map中,map明明有值, 前台获取的为null
- 机器学习模型优化中常见问题和解决思路
- HTTP2.0 HTTPS学习
- 《Python编程:从入门到实践 》[Eric Matthes著] 中文pdf非扫描版
- 【消息队列MQ】从MQ种类说起
- 1080. Graduate Admission 解析
- 关于spark streaming新版本ssc创建不了问题
- cas 4.2.5 返回更多的用户信息
- 多表透视图的制作 第一讲:数据规范化
- LeetCode之Distribute Candies
- PRVG-10122 : ASMLib configuration value