http与Https协议详解介绍

http协议大家可能都耳熟能详了,https并不是一种新的协议,从而保证了数据的安全性。下面介绍https用到的2种加密方式:

http协议大家可能都耳熟能详了,但是它有一系列的缺点,比如:

1.通信时使用明文,这样有可能通信内容会被窃听;

2.不会验证通信方的身份,包括服务器和客户端,特别是服务器,有可能你发送请求的对方是个钓鱼网站;

3.无法验证报文的完整性(准确度),有可能所有的报文会经过黑客的服务器,黑客将内容篡改后进行转发,前后端都不会知晓,神不知鬼不觉;

虽然http协议已经非常强大了,但在安全这一块确实是还有欠妥之处,于是一种安全的http协议-https运用而生。

Https概述

    https并不是一种新的协议,只是在http层下面添加了一层SSL层和TLS层(后面统称为SSL层),SSL层主要是做加密处理,http层直接与SSL层通信,如下图所示:

Https协议详解

一、加密技术

   为了更好的了解https,从而保证了数据的安全性。下面介绍https用到的2种加密方式:

1.共享密钥加密(对称密钥加密)

   加密和解密用同一个密钥的方式,这种方式需要客户端和服务器都知道这个密钥,而单独的发送这个密钥有可能会被窃听的风险,所以如何安全的发送这个密钥又是一个新的难题。

   所以尴尬境地是:发送密钥吧,有可能被黑客窃取;不发送密钥吧,对方就不能解密。

2.公开密钥加密(非对称密钥加密)

   这里使用了2把密钥,一把叫私有密钥(私钥),一把叫公开密钥(公钥),这2个密钥是配对的一套密钥,公钥可以让任何人都知道,而私钥只有自己知道。

   另外,对于一对公钥私钥而言:公钥加密的内容,只有私钥才能解开;而私钥加密的内容,所有公钥都可以解开。

   这种方式可以很好的解决上面对称密钥加密方式的尴尬境地:对于一段内容,发送方可以使用公钥进行加密发送给对方,接收方收到内容后用自己的私钥进行解密,因为这样不用发送解密的私钥,从而不会落入黑客之手。

   有的人会有这样的担心:难道黑客就不能截获加密的内容后破解加密的内容吗?但是我告诉你,破解的难度相当大,就目前的技术来看不太现实。

 

二、混合加密技术-HTTPS

   https采用上面2种加密方式的混合加密机制(公开密钥加密+共享密钥加密),共享密钥加密方式的密钥用公开密钥加密方式加密后发送给对方,然后建立通信后的内容采用共享密钥加密方式。

   为什么采用这种混合方式呢?因为公开加密方式与共享加密方式相比,它的处理速度要慢,所以采用公开加密方式加密一次共享加密方式的密钥后,后面的内容则多次采用共享加密方式,这样可以大大增加效率。

Https协议详解

三、安全隐患

   但是单纯的采用这种混合加密方式,还是会出现安全问题。为什么呢?设想一下,如果第一步向服务器请求公钥的时候,服务器会返回真实的公钥,这时候如果有黑客在中间做一些调包及转发工作,客户端无法知晓对方的服务器是否是真实的服务器。为了解决这一安全问题,于是又添加了证书这一机制。

证书

   数字证书(证书)由数字证书认证机构(简称CA)颁发。CA何许人也?它是客户端和服务器双方都可信赖的权威的第三方机构。它的任务就是颁发证书,一般是给服务器颁发证书,颁发证书后就意味着这个服务器网站是值得信赖的;也可给客户端颁发证书,但一般这种情况比较少见,只用在一些特殊的业务,比如:网上银行等。

 

四、获取证书

   如何获取证书呢?当然是向CA申请及购买,交完钱后,它会给你服务器颁发一个证书。

   也可以免费申请证书,比如:FreeSSL

   有人可能会关心购买证书的价格,这里随便在网上截了个图,可以大概了解下

Https协议详解

五、证书的主要内容

   证书中主要包含有:颁发对象的信息,颁发者,过期时间,数字签名等,完整信息如下图:

Https协议详解

 

   拿百度网站为例,若是https网站,网址前面会有一把锁,可以查看证书,也可导出证书。

Https协议详解

 

Https协议详解

 

 

一、数字签名的重要性

   从上图可以看到,证书中都会有数字签名,那么什么是数字签名呢?

   数字签名其实就是特殊的加密校验码,客户端在收到证书后会用浏览器内置的CA相应公钥根据签名算法对目标网站进行本地签名,如果本地签名与证书的签名不一样,则判定对方服务器是冒牌货,停止传输。

上面提到为什么会用到浏览器内置的CA公钥呢?

   数字证书认证机构的公开密钥必须安全的转交给客户端,那么如何转交又是一件很困难的事(唉!困难重重啊!),于是解决办法是:大多数浏览器开发商在发布版本时,会事先在浏览器内部植入常用认证机构的公开密钥。

 

HTTPS加密传输流程

   通过上面一些基本知识讲解,可以更好的理解https到底是怎么工作,怎么保证网络安全的,流程如下:

1、浏览器请求目标网站,服务器把证书发送给客户端

2、客户端会对证书进行本地签名校验(参考上面的数字签名的重要性)

3、若校验成功,则客户端浏览器会随机生成一个共享加密方式(对称加密)的密钥,然后会从证书中提取公钥对刚刚生成的密钥进行加密,得到密文并发送给服务器

4、服务器收到密文后用自己的私钥进行解密,得到共享加密方式的密钥

5、接下来的一系列的报文传输就采用共享加密方式,因为此时双方(客户端、服务器)都拥有了共享加密方式的密钥,接下来就可以安全的愉快的玩耍了

Https协议详解

 

Python代码中关于SSL验证的问题

   在我们写代码时请求https网站时经常会出现类似“certificate verify failed”这样的错误。

   这样的错误意思是SSL验证出错的问题,说白了,其实就是上面提到的数字签名的校验的错误。以Requests库为例,内部引入了pyOpenSSL库

出现SSL错误的代码:

import requests headers = { 'user-agent' : 'Mozilla/5.0 (Windows NT 6.1; W…) Gecko/20100101 Firefox/59.0' } r = requests.get('https://hcaidcs.phe.org.uk/WebPages/GeneralHomePage.aspx', verify= True) print(r.status_code)

结果如下所示:

Https协议详解

 

   参数verify默认为True。其实就是对证书验证失败,验证的目的就是确认请求的目标服务器是不是真实的服务器。

 

解决方案:

1.我客户端干脆不验证,管你是不是真实的目标网站。这种解决方案是网上最流行的解决方式

2.下载目标网站证书后验证呗

3.安装requests的security 版本

pip3 install requests[security ]

 

解决方案1:不验证

   将verify=False即可,但会出现警告,可以使用requests.packages.urllib3.disable_warnings() 禁用警告

import requests headers = { 'user-agent' : 'Mozilla/5.0 (Windows NT 6.1; W…) Gecko/20100101 Firefox/59.0' } r = requests.get('https://hcaidcs.phe.org.uk/WebPages/GeneralHomePage.aspx', verify= False) print(r.status_code)
Https协议详解

 

 

解决方案2:下载目标网站验证

   将目标网站的证书导出保存起来,如图所示:

Https协议详解

 

 

代码如下:

import requests REQUESTS_CA_BUNDLE= r'e:/certificate/-pheorguk.crt' headers = { 'user-agent' : 'Mozilla/5.0 (Windows NT 6.1; W…) Gecko/20100101 Firefox/59.0' } r = requests.get('https://hcaidcs.phe.org.uk/WebPages/GeneralHomePage.aspx', verify= REQUESTS_CA_BUNDLE) print(r.status_code)

运行结果:200 没有任何错误及警告

Https协议详解

 

 

解决方案3:直接安装安全版的requests,可以有效避免

pip3 install requests[security ]

 

来源:https://zhuanlan.zhihu.com/p/64233102/?utm_id=0