针对 REST api 的 PEM 证书和 TLS 验证

TJB*_*TJB 5 python rest python-requests

我已获得 pem 证书以与第三方进行身份验证。使用证书进行身份验证对我来说是一个新概念。

里面有两个证书和一个私钥。

发行人已告知他们不支持 SSL 验证,但使用 TLS(1.1/1.2)。

我运行了一个脚本,如下所示:

import requests as req
import json

url = 'https://url.com/call'
certificate_file = "C:/certs/cert.pem"

headers = {"Content-Type": "application/json"}
 
req_body ={
    "network":{
                "network_id": 12345
    },
    "branch":{
                "branch_id": 12345,
    },
  "export_period":{
        "start_date_time": "16-11-2021 00:00:00",
        "end_date_time": "17-11-2021 00:00:00"
    }
}
 
jsonObject = json.dumps(req_body)
response = req.post(url,headers=headers,params=jsonObject,verify=certificate_file)
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

SSLError: HTTPSConnectionPool(host='url.com, port=443): 超过最大重试次数,url: /call?%7B%22network%22:%20%7B%22network_id%22:%2012345%7D,%20%22branch %22:%20%7B%22branch_id%22:%2012345%7D,%20%22export_period%22:%20%7B%22start_date_time%22:%20%2216-11-2021%2000:00:00%22, %20%22end_date_time%22:%20%2217-11-2021%2000:00:00%22%7D%7D (由 SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败:无法获取本地颁发者证书 (_ssl.c:1123)')))

希望得到指导,我的直觉告诉我应该针对 TLS 做一些特定的事情,因此会出现 SSL 错误。

Gar*_*her 7

发行者正在使用最新版本的 HTTPS - SSL 是常用术语,但 TLS 是更正确的术语。听起来他们的设置是正确的 - 这意味着您需要使用受信任的客户端证书来调用它,作为 HTTPS 请求的一部分。

我建议首先使用curl 工具执行此操作,以便您可以验证API 是否按预期工作。

curl -s -X GET "https://api.example.com/test" \
--cert ./certs/example.client.pem \
--key ./certs/example.client.key \
--cacert ./certs/ca.pem \
-H "Content-Type: application/json"
Run Code Online (Sandbox Code Playgroud)

如上所述,将证书拆分为单独的文件。听起来其中之一是根证书颁发机构,您需要告诉客户端技术堆栈信任它 - 对于curl,这是使用cacert上面的参数完成的。

一旦它起作用,您就可以在 Python requests 库中遵循相同的方法。我相信这使用certverify参数是这样的。所以看起来你的代码并不遥远。

result = requests.get(
    'https://api.example.com',
    cert=('example.pem', 'example.key'),
    verify='ca.pem')
Run Code Online (Sandbox Code Playgroud)

有关相互 TLS 的更多信息

出于兴趣,如果您想揭开相互 TLS 的神秘面纱并了解更多信息,请查看这些高级 Curity 资源:

其中包括您可以运行的OpenSSL 脚本,以查看分离的证书文件应是什么样子。