我正在使用 python 中的请求调用 REST API,到目前为止,当我设置
verify=False
时已经成功。
现在,我必须使用需要导入的客户端证书进行身份验证,每次使用受密码保护的
cert (.pfx). cert.pfx
时都会收到此错误。
r = requests.post(url, params=payload, headers=headers,
data=payload, verify='cert.pfx')
这是我遇到的错误:
Traceback (most recent call last):
File "C:\Users\me\Desktop\test.py", line 65, in <module>
r = requests.post(url, params=payload, headers=headers, data=payload, verify=cafile)
File "C:\Python33\lib\site-packages\requests\api.py", line 88, in post
return request('post', url, data=data, **kwargs)
File "C:\Python33\lib\site-packages\requests\api.py", line 44, in request
return session.request(method=method, url=url, **kwargs)
File "C:\Python33\lib\site-packages\requests\sessions.py", line 346, in request
resp = self.send(prep, **send_kwargs)
File "C:\Python33\lib\site-packages\requests\sessions.py", line 449, in send
r = adapter.send(request, **kwargs)
File "C:\Python33\lib\site-packages\requests\adapters.py", line 322, in send
raise SSLError(e)
requests.exceptions.SSLError: unknown error (_ssl.c:2158)
我也尝试过 openssl 来获取
.pem
和密钥,但是使用 .pem
并获取 SSL: CERTIFICATE_VERIFY_FAILED
有人可以指导我如何导入证书以及将其放置在哪里吗?我尝试搜索但仍然面临同样的问题。
我也遇到了同样的问题。
verify
参数指的是服务器的证书。您希望使用 cert
参数来指定您的客户端证书。
import requests
cert_file_path = "cert.pem"
key_file_path = "key.pem"
url = "https://example.com/resource"
params = {"param_1": "value_1", "param_2": "value_2"}
cert = (cert_file_path, key_file_path)
r = requests.get(url, params=params, cert=cert)
我遇到了同样的问题,为了解决这个问题,我知道我们必须发送 RootCA 以及证书及其密钥,如下所示,
response = requests.post(url, data=your_data, cert=('path_client_certificate_file', 'path_certificate_key_file'), verify='path_rootCA')
是否可以直接从 Windows 证书存储转移证书? 据我了解,请求库仅接受文件路径。是否有任何适配器或其他库可以使其像请求一样简单?
cert_name = "NAME CERT IN CERT STORE"
def export_cert_to_pem(cert, pem_path):
pem = cert.get_pem()
with open(pem_path, "w") as pem_file:
pem_file.write(pem)
def find_cert_in_trusted_roots(cert_name):
for storename in ("CA", "ROOT"):
with wincertstore.CertSystemStore(storename) as store:
for cert in store.itercerts(usage=wincertstore.SERVER_AUTH):
if cert.get_name().lower() == cert_name.lower():
export_cert_to_pem(cert, cert_name + ".pem")
#export_cert_to_pem(cert, pem_path)
return 1
return 0
cert=find_cert_in_trusted_roots(cert_name)
response = requests.post(some_url, data=your_data, cert=cert)
我也遇到了同样的问题,但我在具有自定义 TSL 或 SSL 证书的企业环境中的 Windows 操作系统中运行。我强烈推荐使用
pip_system_certs
包。此软件包重定向 requests.get()
以使用默认操作系统存储证书。
安装包:
pip install pip_system_certs
我的解决方案涉及部署一个独立的 python 可执行文件来下载文件,因此我必须包含
import pip_system_certs.wrapt_requests
。注意,# noqa: F401
是忽略这一行的 flake8 linting 错误。
import sys
import os
# 'import pip_system_certs' must occur before 'import requests'
import pip_system_certs.wrapt_requests # noqa: F401
import requests
if __name__ == "__main__":
installerUrl = "https://www.python.org/ftp/python/3.10.8/python-3.10.8-amd64.exe"
userPath = os.environ.get("USERPROFILE")
installerPath = os.path.join(os.environ.get("USERPROFILE"), "temp_python_setup", os.path.basename(installerUrl))
if not os.path.isdir(os.path.dirname(installerPath)):
os.makedirs(os.path.dirname(installerPath))
print(f"Installer Path='{installerPath}'")
print(f"Installer URL='{installerUrl}'")
downloadSuccessful = False
proxy = {"http": "http://127.0.0.1:9000", "https": "http://127.0.0.1:9000"}
try:
with open(installerPath, "wb") as f:
print("Downloading %s" % installerPath)
response = requests.get(installerUrl,
stream=True,
verify=True,
allow_redirects=True,
proxies=proxy)
totalSize = response.headers.get('content-length')
if totalSize is None: # no content length header
f.write(response.content)
else:
totalSteps = 80
downloadedSize = 0
totalSize = int(totalSize)
for data in response.iter_content(chunk_size=4096):
downloadedSize += len(data)
f.write(data)
downloadedSteps = int(totalSteps * downloadedSize / totalSize)
sys.stdout.write("\r[%s%s]" % ('=' * downloadedSteps, ' ' * (totalSteps - downloadedSteps)))
sys.stdout.flush()
downloadSuccessful = True
print(" ") # end the progress bar
except Exception as e:
print(" ") # end the progress bar, which may or may not have been started
print(f"Error downloading {installerUrl}: {repr(e)}")
if downloadSuccessful:
print("\nDownload completed successfully")
else:
print("\nDownload failed")