使用python和http.clien在post请求中包含证书的示例

2024-05-19 12:37:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图使用python将xml发布到一个站点。我必须包括一个证书,但不确定如何做到这一点。是否足以在我的计算机上本地指定证书的文件路径?

有人能给我举个例子说明如何在请求中包含证书吗?

import http.client, urllib.parse

xml="""<?xml version="1.0" encoding="UTF-8"?>
<home>
  <bathroom>1</bathroom>
  <kitchen>1</kitchen>
  <street>515</street>
</home>);"""

headers = {"username": "password"}

conn = http.client.HTTPSConnection("someurl.com", cert_file="D:\Users\Username\certificate.p12")
conn.request("POST", "/to/this/place", xml, headers)
response = conn.getresponse()
print(response.status, response.reason)
data = response.read()
print(data)
conn.close()

Tags: clienthttpstreethomedata站点response计算机
2条回答

如果您没有使用自签名证书,并且您的证书是由一个相对可靠的权威机构(即internet上的普通someurl.com)签署的,那么您在建立连接时应该使用系统CA证书。

在Python3.4.3或更高版本中,只需调用HTTPSConnection()而不给它一个证书文件或上下文,就可以做到这一点。

如果使用自签名证书,则可以从本地硬盘加载证书。您需要将私钥包含在证书文件中或指定为密钥文件。如果在您的环境中可能的话,您还需要进行主机验证。请参见verify_modecheck_hostname选项。

import http.client
import ssl

password = input("Key password (enter for none):") or None

xml = """<?xml version="1.0" encoding="UTF-8"?>
<home>
  <bathroom>1</bathroom>
  <kitchen>1</kitchen>
  <street>515</street>
</home>);"""

headers = {"username": "password"}

context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
context.load_cert_chain("cert.pem", "key.pem", password=password)
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = True

conn = http.client.HTTPSConnection("someurl.com", port=443, context=context)

conn.request("POST", "/to/this/place")
response = conn.getresponse()
print(response.status, response.reason)
data = response.read()
print(data)
conn.close()

我用这个来避免让客户进行pkcs12到PEM的转换。基本上重写上下文类以允许它加载pkcs12文件。这对Python很有效

import requests
from OpenSSL import crypto

class Pkcs12Context(requests.packages.urllib3.contrib.pyopenssl.OpenSSL.SSL.Context):
    def __init__(self, method):
        super().__init__(method)
        p12 = crypto.load_pkcs12(open("/certs/client.p12", 'rb').read(), 'password')
        self.use_certificate(p12.get_certificate())
        self.use_privatekey(p12.get_privatekey())

# Monkey-patch the subclass into OpenSSL.SSL so it is used in place of the stock version
requests.packages.urllib3.contrib.pyopenssl.OpenSSL.SSL.Context = Pkcs12Context

r = requests.get('https://example.com')

print(r.text)

相关问题 更多 >