Python Request with Cert



我试图在文件中嵌入证书,而不是通过文件调用它,因为我需要删除脚本的地方,调用文件可能不起作用。

下面是当前代码:

cert = (r"example.crt",r"example.key")
r = requests.post("https://example.com",headers=pHeaders,json=data,cert=cert,verify=False)

这是工作,但我正在寻找类似下面的代码:

cert = """--- cert file in string format ---"""
key = """--- key file in string format ---"""
r = requests.post("https://example.com",headers=pHeaders,json=data,cert=cert,verify=False)

但是证书功能需要一个文件。有解决这个问题的方法吗?

尝试使用tempfile.NamedTemporaryFile():

import requests
import tempfile
cert = """--- cert file in string format ---"""
key = """--- key file in string format ---"""
with tempfile.NamedTemporaryFile() as f_cert, tempfile.NamedTemporaryFile() as f_key:
f_cert.write(cert.encode("utf-8"))
f_cert.seek(0)
f_key.write(key.encode("utf-8"))
f_key.seek(0)
r = requests.get(
"https://example.com", cert=(f_cert.name, f_key.name)
)

永远不要将密钥/证书从ENV或内存保存到文件

这被证明是一种不安全的做法。

执行以下操作:

有一个hack使新版本的requestpyOpenSSL能够处理序列化的base64编码的证书/密钥。您可以使用以下命令将证书和密钥初始序列化为字符串:

~$cat my_precious_private_key.key | base64 

下面是如何使post请求的方法:

from OpenSSL.crypto import FILETYPE_PEM, load_certificate, load_privatekey
import base64
BASE64_CERT_STRING = "<serialized cert>"
BASE64_KEY_STRING = "<serialized key>"
# Hack to use old pyopenssl with new urllib3
import urllib3.contrib.pyopenssl
urllib3.contrib.pyopenssl.inject_into_urllib3()
class Pkcs12Context(
requests.packages.urllib3.contrib.pyopenssl.OpenSSL.SSL.Context
): 
def __init__(self, method):
super().__init__(method)
self.use_certificate(load_certificate(FILETYPE_PEM, base64.b64decode(BASE64_CERT_STRING)))
self.use_privatekey(load_privatekey(FILETYPE_PEM, base64.b64decode(BASE64_KEY_STRING)))

# Save the original context, then replace the request context with your handmade one
original_context = requests.packages.urllib3.contrib.pyopenssl.OpenSSL.SSL.Context
requests.packages.urllib3.contrib.pyopenssl.OpenSSL.SSL.Context = Pkcs12Context
#  Nice! Make a call: 
response = requests.post(
url, 
headers={"Content-Type": "text/xml"}, #  or "Application/text"
data=payload,
timeout=60)
pass  # — process the response
# Do not forget to reset the original context!
requests.packages.urllib3.contrib.pyopenssl.OpenSSL.SSL.Context = original_context

键也可以使用FILETYPE_TEXT

最新更新