Python 请求和 SSLContext

Python Requests and SSLContext

我正在尝试弄清楚如何使用 Request 指定 SSLContext。

我有两个函数,理论上应该做同样的事情,但是带有 Requests 的函数不起作用。

def func_OK(token):
    ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH,cafile='myCA.crt.pem')
    ctx.load_cert_chain(certfile='myprivate.pem')
    url = 'https://my_url.com'
    hdr = {"Content-Type": "application/json","Authorization":"Bearer "+token}
    data = '{"filterList":[{}]}'
    bdata = data.encode('utf-8')
    req = urllib.request.Request(url, headers=hdr)
    resp = urllib.request.urlopen(req, data=bdata, context=ctx)
    content = resp.read()
    data = json.loads(content.decode('utf-8'))
def func_NOK(token):
    import requests
    url = 'https://my_url.com'
    hdr = {"Content-Type": "application/json","Authorization":"Bearer "+token}
    data = '{"filterList":[{}]}'
    bdata = data.encode('utf-8')
    resp = requests.post(url,headers=hdr, data={"filterList":[{}]})

这两个函数之间的唯一区别是 sslContext。 在 func_NOK 中,我尝试:

  1. resp = requests.post(url,headers=hdr, data={"filterList":[{}]}, verify=False) - 它不起作用
  2. resp = requests.post(url,headers=hdr, data={"filterList":[{}]}, cert=('myCA.crt.pem','myprivate.pem')) - 它不起作用
  3. resp = requests.post(url,headers=hdr, data={"filterList":[{}]}, verify="concat_file.crt") 和“concat_file.crt”文件是 'myCA.crt.pem' 和 'myprivate.pem'
  4. 的串联

在任何情况下我都会遇到 SSL 错误。 例如,在我的最后一个示例中,错误消息是:

requests.exceptions.ConnectionError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1131)

我只是想在请求中使用 SSLContext。

ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH,cafile='myCA.crt.pem')
ctx.load_cert_chain(certfile='myprivate.pem')

load_cert_chain 加载用作客户端证书的证书和私钥 - 这将是带有 requestscert 参数。 cafile 描述了它应该用来验证服务器证书的 CA - 这将是请求的 verify 参数。这将导致:

requests.post(..., cert='myprivate.pem', verify='myCA.crt.pem')

我找到我的 cacert.pem 的位置:/home//pyEnv/myEnv/lib/python3.8/site-packages/certifi/cacert.pem

我连接了文件: myCA.crt.pem >> cacert.pem myprivate.pem>> cacert.pem

然后我使用 verify 指定了路径: requests.post(...,verify='/home//pyEnv/myEnv/lib/python3.8/site-packages/certifi/cacert.pem')

我再也没有 ssl 错误了。 但是我检索到 html 消息而不是 json。 可能是我发送到端点的参数有问题。

我使用以下方法解决了它: requests.post(url,headers=hdr,json={"filterList":[{}]}, cert='myprivate.pem')