背景
python报错: ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate
猜测是以下的包发送了https请求,需要建立SSL/TLS握手过程中,需要验证证书的过程中发现本地证书不存在。
解决 unable to get local issuer certificate
一般解决这种问题的步骤就是:
- 发现证书不存在
- 找到查询证书的本地位置
- 在该位置生成证书
解决方法:
查看默认证书位置
既然是SSL找不到证书,我们就可以尝试查到SSL在python中默认查询的证书位置是那里。
谷歌搜索可以知道如下语句可以查询到:
import ssl print(ssl.get_default_verify_paths())
结果:
$ python newPy.py
DefaultVerifyPaths(cafile=None, capath=None, openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/Library/Frameworks/Python.framework/Versions/3.7/etc/openssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/Library/Frameworks/Python.framework/Versions/3.7/etc/openssl/certs')
由此可得证书文件地址。查看该文件路径确实不存在证书文件。
下载ca文件
http://curl.haxx.se/ca/cacert.pem
将下载的文件放到指定位置
将下载的ca文件放到 openssl_cafil 指定位置
cd /Library/Frameworks/Python.framework/Versions/3.7/etc/openssl
mkdir certs
mv ~/Downloads/cacert.pem ./
mv cacert.pem cert.pem
再运行就不会报错了。
keystore证书
$ keytool -genkey -v -keystore health_service_technician.keystore -keyalg RSA -keysize 2048 -validity 10000 -alias technician
证书
我们在使用各种安全验证的时候,都离不开证书。
比如:
- Tomcat、Weblogic、JBoss等Web服务软件,一般使用Java提供的密码库。通过Java Development Kit(JDK)工具包中的Keytool工具,生成Java Keystore(JKS)格式的证书文件。
- Apache、Nginx等Web服务软件,一般使用OpenSSL工具提供的密码库,生成PEM、KEY、CRT等格式的证书文件。
这么多数字证书格式文件,其实都是为了验证身份。
如何理解我们这个需要验证身份呢?
在现代网络中,为了数据不裸奔,张三和李四希望建立一个安全的全双工链接,别人不知道双方通信的内容。
而这就是平时我们所熟知的加密。
例如非对称加密算法,需要两把不同的密钥,这两把密钥组成一对:
- 公钥( public key ),公钥用来对数据进行 加密 ;
- 私钥( private key ),也称为 密钥( secret key ),用来对数据进行 解密 ;
- 公钥和私钥总是成对出现,用公钥加密后得到的密文,必须用对应的私钥才能解密;
加密机制完美解决了裸奔的难题,只需要生成一对密钥:
- 公钥分发给张三,张三先用公钥加密信息,再发李四;
- 李四接到密文,就用自己保管的私钥来解密;其它人就算拿到别人发的密文也解不开,因为私钥只有李四才有。
现在服务器发送信息也一样,服务器先将公钥发给客户端,用公钥保护对称加密密钥,确保通信内容不会被第三方获悉。
但如果客户端连接的服务器是假的呢?如果用户对假网站信以为真,输入了账号密码,那么这些敏感信息都会被假网站窃取。
这种假网站被叫做 钓鱼网站( phishing site ),它们高仿原网站,以假乱真。用户仅凭外观通常难以区分,因此信以为真。在钓鱼网站上输入的账号密码,最终都会被架设网站的黑客收集到。
所以,光靠加密可不行,那么客户端应该如何判断服务器真伪呢?如何识别钓鱼站点呢?
这时候就需要证书了。
那数字证书的作用,是用来认证公钥持有者的身份,以防止第三方进行冒充。
那证书又是怎么来的?又该怎么认证证书呢?
为了让服务端的公钥被大家信任,服务端的证书都是由 CA (Certificate Authority,证书认证机构)签名的,CA 就是网络世界里的公安局、公证中心,具有极高的可信度,所以由它来给各个公钥签名,信任的一方签发的证书,那必然证书也是被信任的。
所以现在,有了加密算法,和权威机构验证身份,我们就建立一个安全的通信了。
生成证书
我们一般会用到以下两个工具生成证书:
keytool 和 openssl
- keytool 是 java JDK 自带的证书管理工具,使用 keytool 可以生成密钥,创建证书。只要装了 jdk,并正确设置了环境变量,就可以之间通过命令行执行 keytool 命令来管理证书。可生成 .keystore 和 .jks 格式的证书
- openssl 则是一个开源的安全套接字层密码库,功能比 keytool 更加丰富。可生成 .pem格式的证书
同时各种格式证书直接也是可以转换的。
可通过openSSL 的命令或者一些在线工具
keytool 生成自签名证书:
keytool -genkeypair -alias serverkey -keystore server.keystore
openssl生成自签名证书:
openssl req -new -x509 -keyout server.key -out server.crt -config openssl.cnf
自签名证书
以上我们自己生成的,未被CA机构验证的证书也叫自签名证书。
虽然使用自签名证书有风险,但也有其用途。
- 免费。自签名证书是免费提供的,任何开发人员都可以申请。
- 随时签发。自签名证书可以随时随地签发,不用等待第三方证书颁发机构的验证和签发。
- 加密。自签名SSL证书使用与其他付费SSL/TLS证书相同的方法加密传输数据。
- 方便。自签名证书不会在一段时间后过期或需要续订,但CA颁发的证书却会在一段时间后过期,还需要续订。
当然了,风险就是可能不被信任, 缺点就是要花钱和时间
当使用自签名证书时,浏览器会发出警告
百度安全的证书:
证书链
证书的验证过程中还存在一个证书信任链
我们向 CA 申请的证书一般不是根证书签发的,而是由中间证书签发的,比如百度的证书,从下图你可以看到,证书的层级有三级:
事实上,操作系统里一般都会内置一些根证书,比如如下的mac
总结
了解了为什么需要数字证书,如何生成数字证书
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。