学习HTTP——HTTPS
前言
因为工作需要,需要用到大量的关于 HTTP 协议的知识,目前掌握的关于 HTTP 请求以及协议的知识都是零散的,打算针对知识盲区系统的学习一些,理清概念。
为什么会出现 HTTPS
因为 HTTP 存在一些难以解决的问题,以下是安全性的问题,这促使产生了 HTTPS。HTTP 在安全性方面,主要有以下的问题。
- HTTP 采用明文传输,内容可能会被窃听
- HTTP 不验证对方的身份,可能会遭遇伪装
- HTTP 不验证内容的完整性,可能会遭遇篡改
既然又了上述问题,那么显然 HTTPS 就是要来解决这些问题。
HTTP + 加密 + 认证 + 完整性验证 = HTTPS
简介
从标题可以看出来,额外添加的功能,实际上正好对应上述 HTTP 所存在的问题,将他们逐个解决就形成了 HTTPS。
这里想先介绍两个概念。
- SSL:Secure Socket Layer 安全套接层, 最初是由网景公司(Netscape)研发,因为发现 HTTP 存在安全性问题。后被IETF(The Internet Engineering Task Force - 互联网工程任务组)标准化后写入(RFCRequest For Comments),RFC里包含了很多互联网技术的规范。
- TLS:由于HTTPS的推出受到了很多人的欢迎,在SSL更新到3.0时,IETF对SSL3.0进行了标准化,并添加了少数机制(但是几乎和SSL3.0无差异),标准化后的IETF更名为TLS1.0(Transport Layer Security 安全传输层协议),可以说TLS就是SSL的新版本3.1,并同时发布“RFC2246-TLS加密协议详解”。
这俩段是从网络上搜索得来的,可以看出来平时所说的 SSL/TLS 其实可以理解成一种加密方式即可,没必要分开来看,后文就称之为 SSL 了。得益于网络结构的分层设计,很容易在 HTTP 协议下加上一层。HTTP 一般直接和 TCP 进行通信,而 HTTPS 首先要经过 SSL 层,然后再和 TCP 通信。其实我学到这里的时候,很容易就能想到,有得必有失,HTTPS 增加了安全性,但是同时降低了性能,但是就目前的趋势来看,安全性肯定更重要,所以往后应该基本上都会采用 HTTPS 的方式吧。
到这里,可以认为 HTTPS 相比与 HTTP,多了一层 SSL,用来保证安全性。
- HTTP:HTTP -> TCP
- HTTPS: HTTP -> SSL -> TCP
加密
首先来看看加密,关于加密,就不得不说两种加密手段,对称加密和非对称加密,这两种方法在 HTTPS 中均有体现。
对称加密
在整个过程中之存在一把密钥,双方都用这一把密钥进行加密。举个例子:A 生成了一把密钥 e,然后将这个密钥以一种安全的方式交给 B。随后,A 利用 e 对信息进行加密并传输给 B,B 利用 e 进行解密,然后同样的用 e 加密信息传递给 A。
这就是对称加密的过程,其中存在一些问题。A 如何将密钥 e 安全的传输给 B ?如果传输过程中密钥 e 被人窃取,那么随后的通信都是不安全的。
非对称加密
非对称加密过程中会存在两把密钥,一把为公开密钥,一把为私有密钥,用一把密钥进行加密的信息,只能用另一把密钥进行解密。公开密钥可以发送给其他人,其他人使用公开密钥对信息加密,传递给生成密钥的人,生成密钥的人用自己的私有密钥对信息进行解密。举个例子:A 生成了一对公有和私有的密钥,私有密钥自己保管,公有密钥传给 B,B 使用 A 的公有密钥对信息进行加密,传递给 A,A 收到信息后使用私有密钥进行解密。因为私有密钥不用传输,因此极大的提升了安全性。
当然如果 A 要向 B 传递加密信息,也是需要 B 生成一对密钥,然后 A 持有 B 的公有密钥,对信息加密后传递给 B。
HTTPS 采用的方式
非对称加密的速度要比对称加密的速度要慢,如果我们可以安全的传递对称加密中的密钥,那么我们是不是就可以只用对称加密方法了呢?
HTTPS 采用一种混合的方式来处理。先使用非对称加密的方式传递对称加密方法中的密钥,随后的通信采用对称加密的方式。
认证
现在有了加密阶段的工作,HTTP 看起来似乎安全了一些,但是还是有问题,如何将对称加密中的公有密钥传递给其他人,你怎么能保证公有密钥不被篡改、替换等?感觉如果只有两个人的话,始终无法解决这个问题。这个时候出现了第三方,权威可信的机构(果然,最后还是得靠信任,如果权威可信的机构某天变得不可信了的话,......)
使用由数字证书认证机构(CA,Certificate Authority)和其相关机关颁发的公开密钥证书,可以很大程度上解决以上的问题。
- 服务器运营方 A,向 CA 提出申请,把公有密钥登记到 CA。
- CA 用自己的私有密钥对 A 的公有密钥签名,并颁发一个数字证书。
- 客户端提前内置了可信的 CA 的公有密钥。
到这里离线的步骤已经做完了,下面是通信的部分。
- 服务器给客户端发送公钥证书
- 客户端收到证书后,利用 CA 的公钥对 证书的签名进行验证,来判断服务器的公钥是否可信。
- 如果可信,则开始后续的通信,也就是“加密”小节 HTTPS 采用的方式。
这里插一句,好奇上网搜了一下证书的价格,发现还是不便宜的,现在似乎是一门生意了。
完整性验证
如何验证内容的完整性?这里用到了消息验证码 (Message Authentication Code),应用层发送数据时会附加一种叫做 MAC(Message Authentication Code)的报文摘要。 MAC能够查知报文是否遭到篡改,从而保护报文的完整性。下面简单介绍一下 MAC。
前提:双方都持有对称加密中的公有密钥
发送方使用一些公开的 MAC 算法,输入消息和公有密钥,产生一个 MAC 值。
发送方将消息与 MAC 一起转发。
在接收到消息和 MAC 后,接收方将接收到的消息和公有密钥 K 送到 MAC 算法中,并重新计算 MAC 值。
接收方检查新计算的 MAC 与从发送方接收到的 MAC 是否相等。如果它们匹配,则接收方接受消息。
如果计算出的 MAC 与发送方发送的 MAC 不匹配,则接收方无法确定是消息被篡改还是来源被篡改,不接受消息。
完整的 HTTPS 通信步骤
基本上 HTTPS 就依靠以上这些步骤来建立安全的通信,下面看一个实际的例子。这里是复制的《图解HTTP》 一书中的案例,向作者致敬!
- 客户端通过发送 Client Hello 报文开始 SSL 通信。报文中包含客户端支持的 SSL 的指定版 本、加密组件(Cipher Suite)列表(所使用的加密算法及密钥长度等)。
- 服务器可进行 SSL 通信时,会以 Server Hello 报文作为应答。和客户端一样,在报文中包含 SSL 版本以及加密组件。服务器的加密组件内容是从接收到的客户端加密组件内筛选出来的。
- 之后服务器发送 Certificate 报文。报文中包含公开密钥证书。
- 最后服务器发送 Server Hello Done 报文通知客户端,最初阶段的 SSL 握手协商部分结束。
- SSL 第一次握手结束之后,客户端以 Client Key Exchange 报文作为回应。报文中包含通信加 密中使用的一种被称为 Pre-master secret 的随机密码串。该报文已用步骤 3 中的公开密钥进行加密。
- 接着客户端继续发送 Change Cipher Spec 报文。该报文会提示服务器,在此报文之后的通信 会采用 Pre-master secret 密钥加密。
- 客户端发送 Finished 报文。该报文包含连接至今全部报文的整体校验值。这次握手协商是否 能够成功,要以服务器是否能够正确解密该报文作为判定标准。
- 服务器同样发送 Change Cipher Spec 报文。
- 服务器同样发送 Finished 报文。
- 服务器和客户端的 Finished 报文交换完毕之后,SSL 连接就算建立完成。当然,通信会受到 SSL 的保护。从此处开始进行应用层协议的通信,即发送 HTTP 请求。
- 应用层协议通信,即发送 HTTP 响应。
- 最后由客户端断开连接。断开连接时,发送 close_notify 报文。上图做了一些省略,这步之 后再发送 TCP FIN 报文来关闭与 TCP 的通信。
总结
- HTTPS 比 HTTP 更加安全,主要是利用了 SSL/TLS,HTTP 先和它们通信,然后再经过TCP。
- SSL 利用非对称加密来建立 SSL,后续通过对称加密来传递信息。
- SSL 的非对称加密的公钥通过 CA 颁发的证书,利用 CA 的公钥来验证,一般内置在客户端中。
- 报文的完整性,通过消息验证码(MAC)来验证。
参考资料
学习HTTP——HTTPS的更多相关文章
- haproxy学习之https配置
haproxy学习之https配置 原文 http://www.cnblogs.com/ilanni/p/4941056.html 如何配置https,以及https在实际生产环境中的应用. ...
- 分享一个编程学习网站:https://github.com/justjavac/free-programming-books-zh_CN
分享一个编程学习网站:https://github.com/justjavac/free-programming-books-zh_CN
- 烂泥:haproxy学习之https配置
本文由ilanniweb提供友情赞助,首发于烂泥行天下 想要获得更多的文章,可以关注我的微信ilanniweb. 在前一段时间,我写了几篇有关学习haproxy的文章.今天我们再来介绍下haproxy ...
- K8S 使用NFS 创建PV和PVC的例子 学习From https://blog.csdn.net/xts_huangxin/article/details/51494472
1. 获取资料 网址: https://blog.csdn.net/xts_huangxin/article/details/51494472 感谢原作者 这里面 按照自己的机器情况进行了学习模仿 ...
- HTTP学习三:HTTPS
HTTP学习三:HTTPS 1 HTTP安全问题 HTTP1.0/1.1在网络中是明文传输的,因此会被黑客进行攻击. 1.1 窃取数据 因为HTTP1.0/1.1是明文的,黑客很容易获得用户的重要数据 ...
- HTTPS的学习
HTTPS的学习总结 HTTPS学习总结 简述 HTTPS对比HTTP就多了一个安全层SSL/TLS,具体就是验证服务端的证书和对内容进行加密. 先来看看HTTP和HTTPS的区别 我用AFN访问 ...
- https学习笔记二----基础密码学知识和python pycrypto库的介绍使用
在更详细的学习HTTPS之前,我也觉得很有必要学习下HTTPS经常用到的加密编码技术的背景知识.密码学是对报文进行编解码的机制和技巧.可以用来加密数据,比如数据加密常用的AES/ECB/PKCS5Pa ...
- UWP学习记录1-开端
UWP学习记录1-开端 1.背景 针对不同基础的人,学习的路线自然是不同的.这篇文章记录的是我个人的学习路线,或者说笔记.我对自己的技术状态的定义是: A.有很好的windows平台编程基础: B.有 ...
- NNVM打造模块化深度学习系统(转)
[摘录理由]: 之所以摘录本文,主要原因是:该文配有开源代码(https://github.com/dmlc/nnvm):读者能够直接体会文中所述的意义,便于立刻展开研究. MXNet专栏 :NNVM ...
随机推荐
- 关于kafka客户端版本与服务端版本不一致导致的一次坑
上周开发了一个功能,需要使用kafka接上游数据并入库,本地开发时,自己安装了一个kafka服务,开发测试时使用本地的kafka服务给主题发消息,然后在自己本地的代码中进行调试.使用的kafka版本如 ...
- 四种类型的数据节点 Znode?
1.PERSISTENT-持久节点 除非手动删除,否则节点一直存在于 Zookeeper 上 2.EPHEMERAL-临时节点 临时节点的生命周期与客户端会话绑定,一旦客户端会话失效(客户端与 zoo ...
- redis 为什么是单线程的?
一.Redis为什么是单线程的? 因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽.既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理 ...
- 什么是JDK?什么是JRE?说说它们之间的区别?
JDK (Java Development Kit) JDK是整个Java的核心,包括了Java运行环境JRE(Java Runtime Envirnment),一堆Java工具(javac,ja ...
- Effective Java —— 使类和成员的可访问性最小化
本文参考 本篇文章参考自<Effective Java>第三版第十五条"Minimize the accessibility of classes and members&quo ...
- SVN之屏蔽不需要提交的xml等文件
SVN之屏蔽不需要提交的xml等文件 在默认"Default changelist"中是我们正常需要提交的文件 在"不需要提交的文件"中存储的是一些线下环境需要 ...
- scrapy 如何链接有密码的redis scrapy-redis 设置redis 密码 scrapy-redis如何为redis配置密码
# 使用scrapy_redis的调度器SCHEDULER = "scrapy_redis.scheduler.Scheduler"# 使用scrapy_redis的去重机制DUP ...
- [译] 沙箱中的间谍 - 可行的 JavaScript 高速缓存区攻击
原文 The Spy in the Sandbox – Practical Cache Attacks in Javascript 相关论文可在 https://github.com/wyvernno ...
- IO流的简单实现
IO流的几种实现方式 学习目标: 例题: 字节输出流 字节输入流 字符输入流 字符输出流 学习目标: 熟练掌握IO流的基本实现方式 例题: 字节输出流 代码如下: public class Outpu ...
- DOS控制台
:win+r--cmd--回车* A:d: 回车 盘符切换* B:dir(directory):列出当前目录下的文件以及文件夹* C:cd (change directory)改变指定目录(进入指定目 ...