我尝试使用基于证书的身份验证在 python 中向提供 REST api 的给定服务器发送 REST 请求,但经过数小时的搜索和尝试后,我认为我需要帮助。
我有来自上述服务器的签名证书以及该证书的密钥。 服务器本身也提供 https 证书。
我尝试了库httplib.HTTPSConnection:
导入httplib 导入urllib clientCert = "客户端.crt" clientKey = "客户端.key" serverCert = '服务器.crt' serverApi =“/api/getExample” serverHost =“restapi.example.com” 服务器端口 = 443 请求方法=“POST” params = urllib.urlencode({'someId': 'myId'}) headers = {“内容类型”:“application/x-www-form-urlencoded”,“接受”:“application/json”} conn = httplib.HTTPSConnection(serverHost, serverPort, key_file=clientKey, cert_file=clientCert) conn.request(requestMethod, serverApi, params, headers) 响应 = conn.getresponse() conn.getresponse() conn.close()
我明白了
ssl.SSLError: SSL: CERTIFICATE_VERIFY_FAILED
我能够在“requests”库的帮助下让它运行。
import json
import requests
clientCrt = "cc.crt"
clientKey = "ck.key"
url = "https://example.com/api"
payload = { "someId": "myID" }
certServer = 'cs.crt'
headers = {'content-type': 'application/json'}
r = requests.post(url, data=json.dumps(payload), verify=certServer,
headers=headers, cert=(clientCrt, clientKey))
print(r.status_code)
print(r.json())
就这么简单
谢谢你,卡罗,
我设法通过使用证书链、证书和私钥的单个文件来使其工作。在此之前,我遇到了错误:
HTTPSConnectionPool(host='host, port=4443): Max retries exceeded with url: /api/endpoint (Caused by SSLError(SSLError(9, '[SSL] PEM lib (_ssl.c:3921)')))
。
这是我使用的改编代码:
import json
import requests
clientCertsAndKey = 'certChainAndCertAndKey.pem'
url = 'https://example.com/api'
payload = { 'someId': 'myID' }
certServer = 'cs.crt'
headers = {'content-type': 'application/json'}
try:
r = requests.post(url, data=json.dumps(payload), verify=certServer,
headers=headers, cert=clientCertsAndKey)
print(r.status_code)
print(r.json())
except requests.exceptions.SSLError as ssl_error:
print(f'SSL error: {ssl_error}')
请记住,对于使用单个文件作为客户端证书+私钥的任何人,请确保证书链(颁发证书的实体的证书)也包含在该文件中。这帮助我克服了前面提到的 SSL 错误。