我试图在文件中嵌入证书,而不是通过文件调用它,因为我需要删除脚本的地方,调用文件可能不起作用。
下面是当前代码:
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使新版本的request
和pyOpenSSL
能够处理序列化的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
。