一、哪些情况可能会遇到这个错误?
使用urllib.request.urlopen请求https资源时(不限系统)
使用requests的get或post方法请求https资源时(不限系统)
MAC OS中使用上面任意库请求https资源时
使用pip install安装软件包时
使用setup.py upload 上传软件包到仓库时
使用其他python脚本或命令,内部使用了情况1或情况2的相关接口,访问https资源时。
使用Python类库请求一些https网站正常,请求另外一些https网站遇到这个错误
二、为什么会出现这个错误?这个错误说明了什么?
要想知道这个错误为什么会出现,是什么导致了这个错误,需要简单了解下SSL和证书的相关知识:
2.1 HTTPS的简要知识
在HTTPS普及之前,大多数网站都使用明文传输的HTTP协议。用户和网站的访问内容,密码等在家庭路由器、小区交换机、公网节点等都是可以被中间人看到、拦截或修改的,即主要存在泄漏、篡改、假冒三大安全问题。
为了解决上面的安全问题,就需要对传输内容进行加密,常规的加密算法包括对称加密和非对称加密,因为对称加密存在秘钥不便传输问题,HTTPS在连接的初始建立阶段使用的是非对称加密算法,加密连接创建后再切换到对称加密算法提高性能。
非对称加密的特点:
存在公钥和私钥两个秘钥,一般公钥是任何人都可以拿到的。
公钥加密的内容可以用私钥解密,反之亦然。
用公钥或私钥加密很简单,但根据密文和公钥破解私钥很难。
HTTPS协议使用的是RSA非对称加密技术。HTTPS通信流程如下:
TCP三次握手
客户端向服务器发起HTTPS请求
服务器返回数字证书
客户端用本地内置证书验证服务器证书有效性,如果证书无效中断整个流程;证书有效则生成随机值作为对称秘钥,并使用证书加密对称秘钥;
客户端把证书加密后的对称秘钥发送给服务器
服务器用私钥解密获得对称秘钥,再用对称秘钥加密内容发给客户端
客户端收到服务器对称加密的内容,可以正确解密,至此加密连接创建完成。
流程3的服务器证书里面存储的就是网站的公钥。我们遇到的错误就是发生在流程4中,验证证书无效。
更多关于HTTPS的知识
2.2 客户端是如何验证服务器证书的呢?
服务器的证书是包含了网站主要信息、公钥、数字签名等信息的一个文件。
非对称加密只是确保了网络连接的不被窃听和篡改,但包含公钥的证书是谁都可以签发的,那拿到一个百度证书如何确定这个证书就是百度的证书呢?公钥一般几百上千个字符,全球十几亿个网站证书全都记录下来也不现实,所以就提出了另一个概念:CA(Certificate Authority)证书签发机构。客户端和服务器端都信任且保存了CA的证书,作为根证书;如果一个证书是由CA签发的二级证书,那我们可以用CA的证书验证它的有效性;如果服务器的证书是由验证过的二级证书签发的,那么我们也可以验证服务器的证书的有效性;这样的一个逐层验证过程即形成了证书链。
根证书是直接保存在操作系统中的,凡是根证书直接或间接签发的证书都可以信任;按这样的原理,我们可以验证成千上万的网站证书是否有效;截止2020/08,MacOS内置了168个根证书,Windows内置了255个根证书,Chrome和FireFox使用自带的证书库。
需要注意的是,虽然操作系统内置了根证书,但一些软件可能并未使用系统根证书,而是在软件安装时自身带了一些证书作为根证书。(如pythonpython的requests库和pip等库使用包内置的根证书,有些浏览器也使用的内置根证书而非系统根证书),如果电脑装有everything,搜索cacert.pem可以发现很多文件,这些都是各个软件自带的根证书。
此外,证书链可能不止一条!计算机本地保存的根证书一般是几十年有效期,由根证书颁发的二级证书一般是几年有效期。如果你的电脑买了有两三年了,有可能出现买的时候根证书还有效,现在根证书过期的情况,从而导致一些网站无法访问。从浏览器访问网站是按浏览器的根证书库形成证书链,浏览器的根证书库由浏览器维护和更新,所以一直显示是正常的。而windows操作系统根证书库由windows更新维护,python ssl使用的是操作系统的根证书库,所以也可能出现浏览器中证书正常,python中报证书过期或无效问题。(PS:Windows10家庭版似乎没有根证书自动更新。。)
虽然服务器部署证书的时候,一般都是部署的完整证书链,但客户端不一定会使用网站提供的证书链;如果服务器证书链的根证书在客户端本地根证书库中不存在,客户端就会从本地根证书库中尝试自己构造一个可信的证书链,构造过程中可能会使用过期的证书。
这是一个中间证书过期的例子
2.2.1 常见的证书错误有:
证书不可信(ERR_CERT_AUTHORITY_INVALID)【最多】
由不可信的CA机构签发的证书,比如自签发的证书,或者操作系统缺失CA根证书。
证书名称不匹配(ERR_CERT_COMMON_NAME_INVALID)
证书是签发给www.baidu.com,但访问的网站是baidu.com,也会出现这个问题。
证书过期(ERR_CERT_DATE_INVALID)
证书有效期到期,或本地时间不正确(根据行业标准,网站SSL证书有效期不能超过398天)
证书被吊销(ERR_CERT_REVOKED)
虚假信息申请得到的证书,或私钥被泄漏,或签发错误等会出现这个情况
一般性SSL错误(ERR_SSL_PROTOCOL_ERROR)
证书部署错误,客户端SSL协议不匹配,证书字段缺失等问题。
三、哪些原因可能会导致证书错误?
根据上面分析,造成证书错误的原因有很多,但笼统的可以分为两类:证书无效报错,证书有效报错。
判断网站证书是否有效建议通过myssl.com,输入网站域名,可以测试出网站安全等级、支持的TLS版本、证书问题、支持浏览器版本等情况。
3.1 证书无效报错
3.1.1 网站使用自签发证书
自签名的证书因为不是由根证书逐层签发的,所以任意一台电脑访问这种网站时都会弹出连接不安全的警告。
现象:这个网站在任意一台电脑访问都会报证书错误。
3.1.2 证书和域名不匹配
证书分为单域名证书和通配符证书;单域名证书需要和网站域名完全匹配才能验证通过,比如申请了www.baidu.com的单域名证书,部署在news.baidu.com上面就会出现证书名称不匹配错误。通配符证书一般是针对主域名申请,如“*.baidu.com”,可以部署在其下所有子域名网站上。
转载请注明出处:
未经允许不得转载:lxfamn » SSL加密 https