用python 请求https api,返回SSL报错:
SSLError: [Errno 1] _ssl.c:504: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
问题排查:
1,一般这种情况都是证书是自签名的,本地找不到可用的CA证书。
需下载对应的CA证书,然后导入方法简述:
OSX/macOS/iOS
执行如下命令导入证书:
sudo security add-trusted-cert -d -r trustRoot -k "/Library/Keychains/System.keychain" xxx-ca-rsa.crt
Windows
双击下载的证书文件后按提示导入证书到受信任的根证书颁发机构 > 证书中。
或 certutil -addstore -f "ROOT" xxx-ca-rsa.crt
Linux
Ubuntu: cp xxx-ca-rsa.crt /usr/local/share/ca-certificates/xxx-ca-rsa.crt && update-ca-certificates –fresh
Arch: sudo trust anchor –store xxx-ca-rsa.crt
其他发行版本请自行查找使用方法,:(
Java
导入CA: ${JAVA_HOME}/bin/keytool -import -trustcacerts -keystore ${JAVA_HOME}/jre/lib/security/cacerts -storepass changeit -alias RSA-CA -file xxx-ca-rsa.crt
查看CA: ${JAVA_HOME}/bin/keytool -list -v -keystore ${JAVA_HOME}/jre/lib/security/cacerts -storepass changeit
2. 如果还有问题,可能是一些python库读取的证书位置和系统默认安装路径不一致,导致找不到证书文件:
如果使用的requests库,可以在环境变量中添加REQUESTS_CA_BUNDLE变量指向有效的CA证书文件,
export REQUESTS_CA_BUNDLE=/usr/local/share/ca-certificates/xxx-ca-rsa.crt
但是这个方法不是很好,可能导致访问其他正常的https又出现解析问题。
查看python httplib库,在connnect建立的时候有一个配置是:
VERIFY_CERTS_DEFAULT = None
CA_CERTS = None
try:
import certifi
CA_CERTS = certifi.where()
except ImportError:
pass
可以在本地执行下本语句,看下CA_CERTS指向的路径,我本机测试指向如下:
/Library/Python/2.7/site-packages/certifi/cacert.pem
把对应的CA证书内容添加到文件中即可。
/Library/Python/2.7/site-packages/certifi/cacert.pem