我正在编写一个简单的脚本,涉及CAS、jspring安全检查、重定向等。我想使用Kenneth Reitz的python请求,因为它是一个伟大的作品!然而,CAS需要通过SSL进行验证,所以我必须先通过这一步。我不知道Python请求想要什么?这个SSL证书应该驻留在哪里?
Traceback (most recent call last):
File "./test.py", line 24, in <module>
response = requests.get(url1, headers=headers)
File "build/bdist.linux-x86_64/egg/requests/api.py", line 52, in get
File "build/bdist.linux-x86_64/egg/requests/api.py", line 40, in request
File "build/bdist.linux-x86_64/egg/requests/sessions.py", line 209, in request
File "build/bdist.linux-x86_64/egg/requests/models.py", line 624, in send
File "build/bdist.linux-x86_64/egg/requests/models.py", line 300, in _build_response
File "build/bdist.linux-x86_64/egg/requests/models.py", line 611, in send
requests.exceptions.SSLError: [Errno 1] _ssl.c:503: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
我找到了一个解决类似问题的具体方法。这个想法是指向存储在系统中的cacert文件,并由另一个基于ssl的应用程序使用。
在Debian中(我不确定在其他发行版中是否相同),证书文件(.pem)存储在/etc/ssl/certs/所以,这是为我工作的代码:
import requests
verify='/etc/ssl/certs/cacert.org.pem'
response = requests.get('https://lists.cacert.org', verify=verify)
为了猜测pem文件的选择,我已经浏览到url并检查哪个证书颁发机构(CA)生成了证书。
编辑:如果你不能编辑代码(因为你正在运行第三个应用程序),你可以尝试直接将pem证书添加到/usr/local/lib/python2.7/dist-packages/requests/cacert。Pem(例如将其复制到文件的末尾)。
我在使用aws boto3时遇到了同样的问题和ssl证书验证失败的问题,通过检查boto3代码,我发现没有设置REQUESTS_CA_BUNDLE,所以我通过手动设置来修复这两个问题:
from boto3.session import Session
import os
# debian
os.environ['REQUESTS_CA_BUNDLE'] = os.path.join(
'/etc/ssl/certs/',
'ca-certificates.crt')
# centos
# 'ca-bundle.crt')
对于aws-cli,我想在~/中设置REQUESTS_CA_BUNDLE。Bashrc将修复这个问题(没有测试,因为我的aws-cli没有它也能工作)。
REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt # ca-bundle.crt
export REQUESTS_CA_BUNDLE
这与@rafael-almeida的回答类似,但我想指出的是,对于2.11+的请求,没有3个值可以验证,实际上有4个:
True:根据请求的内部可信ca进行验证。
False:完全跳过证书验证。(不推荐)
CA_BUNDLE文件的路径。请求将使用它来验证服务器的证书。
包含公共证书文件的路径。请求将使用它来验证服务器的证书。
我剩下的答案是关于#4,如何使用包含证书的目录来验证:
获取所需的公共证书,并将它们放在一个目录中。
严格地说,您可能“应该”使用带外方法获取证书,但您也可以使用任何浏览器下载它们。
如果服务器使用证书链,请确保获取链中的每个证书。
根据请求文档,包含证书的目录必须首先使用“rehash”实用程序(openssl rehash)进行处理。
(这需要openssl 1.1.1+,并且不是所有的Windows openssl实现都支持rehash。如果openssl rehash对你不起作用,你可以尝试在https://github.com/ruby/openssl/blob/master/sample/c_rehash.rb上运行rehash ruby脚本,尽管我还没有尝试过。)
我在让请求识别我的证书时遇到了一些麻烦,但是在我使用openssl x509 -outform PEM命令将证书转换为Base64 . PEM格式后,一切都完美地工作了。
你也可以只做惰性重哈希:
try:
# As long as the certificates in the certs directory are in the OS's certificate store, `verify=True` is fine.
return requests.get(url, auth=auth, verify=True)
except requests.exceptions.SSLError:
subprocess.run(f"openssl rehash -compat -v my_certs_dir", shell=True, check=True)
return requests.get(url, auth=auth, verify="my_certs_dir")