超文本传输协议,是一个基于请求与响应,无状态无连接的,应用层的协议,常基于TCP/IP协议传输数据
<协议>://<域名>:<端口>/<路径>
HTTP通常跑在TCP/IP协议栈之上,依靠IP协议实现寻址和路由、TCP协议实现可靠数据传输、DNS协议实现域名查找、SSL/TLS协议实现安全通信
经由HTTP进行通信,利用SSL/TLS建立全信道,加密数据包。HTTPS使用的主要目的是提供对网站服务器的身份认证,同时保护交换数据的隐私与完整性。关于TLS就是SSL的升级版本。
SSL 安全套接层(Secure Sockets Layer)
TSL 传输层安全(Transport Layer Security)
如果信息在传输过程中被劫持,传输的内容就完全暴露了,他还可以篡改传输的信息且不被双方察觉,这就是中间人攻击。所以我们才需要对信息进行加密。最直接的加密方式就是对称加密。
对称加密就是加密和解密使用同一个密钥。如AES、DES。加解密过程:
问题是client-random和server-random都是明文的,也就是密钥的相关信息在传输过程中很可能被窃取,中间人只要计算出密钥任何人都能解密,所以不能让第三方拿到密钥
如果通信双方都各自持有同一个密钥,且没有别人知道,这两方的通信安全当然是可以被保证的(除非密钥被破解)。
怎么办?所以我们就需要神奇的非对称加密
为什么会出现非对称加密,就是因为对称加密的算法是可以被攻破的,(最坏的情况下穷举攻击能攻破的
非对称加密分为两个密钥:公钥和私钥。公钥是谁都能有,用于对信息加密,只有私钥才能解密。
用公钥加密的内容必须用私钥才能解开,同样,私钥加密的内容只有公钥能解开。
通俗版:
总结:无法保证服务器发送给浏览器的这条线路的数据安全。
浏览器和服务器都各自有一对公钥和私钥
HTTPS的加密却没使用这种方案,最主要的原因是非对称加密算法非常耗时,特别是加密解密一些较大数据的时候有些力不从心,而对称加密快很多
TLS实际用的是两种算法的混合加密。**通过 非对称加密算法 交换 对称加密算法 的密钥,交换完成后,再使用对称加密进行加解密传输数据。**这样就保证了会话的机密性。过程如下
然后开始数据加密传输
这样即便被截持,中间人没有私钥就拿不到pre-random,就无法生成最终密钥
通俗版:
中间人的确无法得到浏览器生成的密钥B,这个密钥本身被公钥A加密了,只有服务器才有私钥A’解开拿到它呀!然而中间人却完全不需要拿到密钥A’就能干坏事了
这样在双方都不会发现异常的情况下,中间人得到了密钥X。根本原因是浏览器无法确认自己收到的公钥是不是网站自己的。
那么下一步就是解决下面这个问题:
网站在使用HTTPS前,需要向“CA机构”申请颁发一份数字证书,数字证书里有证书持有者、证书持有者的公钥等信息,服务器把证书传输给浏览器,浏览器从证书里取公钥就行了,证书就如身份证一样,可以证明“该公钥对应该网站”。
摘要算法:主要用于保证信息的完整性。常见的MD5算法、散列函数、hash函数都属于这类算法,其特点就是单向性、无法反推原文
图中左侧是数字签名的制作过程,右侧是验证过程
数字签名的制作过程:
明文和数字签名共同组成了数字证书,这样一份数字证书就可以颁发给网站了
通俗版:
证书认证又分为单向认证和双向认证
不过大多数https服务器都是单向认证,如果服务器需要验证客户端的身份,一般通过用户名、密码、手机验证码等之类的凭证来验证。只有更高级别的要求的系统,比如大额网银转账等,就会提供双向认证的场景,来确保对客户身份提供认证性
另外在申请和使用证书的过程中,需要注意
最显然的是性能问题,前面我们已经说了非对称加密效率较差,证书信息一般较长,比较耗时。而hash后得到的是固定长度的信息(比如用md5算法hash后可以得到固定的128位的值),这样加密解密就会快很多。当然还有安全上的原因,这部分内容相对深一些,感兴趣的可以看这篇解答:详情
即“该公钥是否对应该网站/机构等”,那这个CA机构的公钥是不是也可以用数字证书来证明?没错,操作系统、浏览器本身会预装一些它们信任的根证书,如果其中有该CA机构的根证书,那就可以拿到它对应的可信公钥了
显然每次请求都经历一次密钥传输过程非常耗时,那怎么达到只传输一次呢?靠“session”。服务器会为每个浏览器(或客户端软件)维护一个session ID,在TSL握手阶段传给浏览器,浏览器生成好密钥传给服务器后,服务器会把该密钥存到相应的session ID下,之后浏览器每次请求都会携带session ID,服务器会根据session ID找到相应的密钥并进行解密加密操作,这样就不必要每次重新制作、传输密钥了!
传统的TLS握手也就是RSA握手;
详细的RSA握手
现在主流的TLS1.2版本的握手,也就是ECDHE握手。
客户端在第一次发送HTTPS请求的时候,会把 client_random、TSL版本号、加密套件列表发送给服务器
服务器在接收到之后确认TSL的版本号,同时发送 server_random、server_params、需要使用的加密套件、以及自己的证书给客户端
客户端在收到这些信息之后,首先是会对服务器的证书进行验证(也就是题目7),若是验证成功则会传递一个 client_params 给服务器
与此同时客户端会通过ECDHE算法计算出一个pre_random,其中是传入了两个参数,一个是 client_params,还一个是 server_params。(也就是说:ECDHE(client_params, server_params) = per_random)
这时候客户端就同时拥有了 client_random、server_random、pre_random,它会将这三个参数通过一个伪随机函数计算得出最终的secret,这个secret就是它们后续通信所要用的对称密钥。
而在客户端生成完secret之后,会给服务器发送一个收尾消息,告诉服务器之后都要用对称加密,且对称加密的算法是用第一次约定好的。
服务器它在接收到刚刚传递过来的client_params之后,也会使用和客户端一样的方式生成secret,并且也会发送一个收尾消息给客户端。
当双方都收到收尾消息并验证成功之后,握手就结束了。后面开始用这个secret对称密钥加密报文进行传输。
(ECDHE基于椭圆曲线离散对数,传入的两个参数也被叫做椭圆曲线的公钥)
ECDHE握手和RSA握手又有什么区别
向前安全性
当使用HTTPS进行第一次请求时,客户端与服务器之间会进行SSL/TLS握手的过程,以建立加密通信信道。