一、加密技术
为了更好的了解https,从而保证了数据的安全性。下面介绍https用到的2种加密方式:
1.共享密钥加密(对称密钥加密)
加密和解密用同一个密钥的方式,这种方式需要客户端和服务器都知道这个密钥,而单独的发送这个密钥有可能会被窃听的风险,所以如何安全的发送这个密钥又是一个新的难题。
所以尴尬境地是:发送密钥吧,有可能被黑客窃取;不发送密钥吧,对方就不能解密。
2.公开密钥加密(非对称密钥加密)
这里使用了2把密钥,一把叫私有密钥(私钥),一把叫公开密钥(公钥),这2个密钥是配对的一套密钥,公钥可以让任何人都知道,而私钥只有自己知道。
另外,对于一对公钥私钥而言:公钥加密的内容,只有私钥才能解开;而私钥加密的内容,所有公钥都可以解开。
这种方式可以很好的解决上面对称密钥加密方式的尴尬境地:对于一段内容,发送方可以使用公钥进行加密发送给对方,接收方收到内容后用自己的私钥进行解密,因为这样不用发送解密的私钥,从而不会落入黑客之手。
有的人会有这样的担心:难道黑客就不能截获加密的内容后破解加密的内容吗?但是我告诉你,破解的难度相当大,就目前的技术来看不太现实。
二、混合加密技术-HTTPS
https采用上面2种加密方式的混合加密机制(公开密钥加密+共享密钥加密),共享密钥加密方式的密钥用公开密钥加密方式加密后发送给对方,然后建立通信后的内容采用共享密钥加密方式。
为什么采用这种混合方式呢?因为公开加密方式与共享加密方式相比,它的处理速度要慢,所以采用公开加密方式加密一次共享加密方式的密钥后,后面的内容则多次采用共享加密方式,这样可以大大增加效率。
三、安全隐患
但是单纯的采用这种混合加密方式,还是会出现安全问题。为什么呢?设想一下,如果第一步向服务器请求公钥的时候,服务器会返回真实的公钥,这时候如果有黑客在中间做一些调包及转发工作,客户端无法知晓对方的服务器是否是真实的服务器。为了解决这一安全问题,于是又添加了证书这一机制。
数字证书(证书)由数字证书认证机构(简称CA)颁发。CA何许人也?它是客户端和服务器双方都可信赖的权威的第三方机构。它的任务就是颁发证书,一般是给服务器颁发证书,颁发证书后就意味着这个服务器网站是值得信赖的;也可给客户端颁发证书,但一般这种情况比较少见,只用在一些特殊的业务,比如:网上银行等。
四、获取证书
如何获取证书呢?当然是向CA申请及购买,交完钱后,它会给你服务器颁发一个证书。
也可以免费申请证书,比如:FreeSSL
有人可能会关心购买证书的价格,这里随便在网上截了个图,可以大概了解下
五、证书的主要内容
证书中主要包含有:颁发对象的信息,颁发者,过期时间,数字签名等,完整信息如下图:
拿百度网站为例,若是https网站,网址前面会有一把锁,可以查看证书,也可导出证书。
一、数字签名的重要性
从上图可以看到,证书中都会有数字签名,那么什么是数字签名呢?
数字签名其实就是特殊的加密校验码,客户端在收到证书后会用浏览器内置的CA相应公钥根据签名算法对目标网站进行本地签名,如果本地签名与证书的签名不一样,则判定对方服务器是冒牌货,停止传输。
上面提到为什么会用到浏览器内置的CA公钥呢?
数字证书认证机构的公开密钥必须安全的转交给客户端,那么如何转交又是一件很困难的事(唉!困难重重啊!),于是解决办法是:大多数浏览器开发商在发布版本时,会事先在浏览器内部植入常用认证机构的公开密钥。
通过上面一些基本知识讲解,可以更好的理解https到底是怎么工作,怎么保证网络安全的,流程如下:
1、浏览器请求目标网站,服务器把证书发送给客户端
2、客户端会对证书进行本地签名校验(参考上面的数字签名的重要性)
3、若校验成功,则客户端浏览器会随机生成一个共享加密方式(对称加密)的密钥,然后会从证书中提取公钥对刚刚生成的密钥进行加密,得到密文并发送给服务器
4、服务器收到密文后用自己的私钥进行解密,得到共享加密方式的密钥
5、接下来的一系列的报文传输就采用共享加密方式,因为此时双方(客户端、服务器)都拥有了共享加密方式的密钥,接下来就可以安全的愉快的玩耍了
在我们写代码时请求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)
结果如下所示:
参数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)
解决方案2:下载目标网站验证
将目标网站的证书导出保存起来,如图所示:
代码如下:
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 没有任何错误及警告
解决方案3:直接安装安全版的requests,可以有效避免
pip3 install requests[security ]
来源:https://zhuanlan.zhihu.com/p/64233102/?utm_id=0