3

我正在尝试使用 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()
4

2 回答 2

8

我用它来避免让客户进行 pkcs12 到 PEM 的转换。基本上覆盖上下文类以允许它加载 pkcs12 文件。这适用于python3

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)
于 2018-04-06T16:00:18.223 回答
4

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

您可以通过调用 HTTPSConnection() 来做到这一点,而无需在 Python 3.4.3 或更高版本中为其提供证书文件或上下文。

如果您使用的是自签名证书,那么是的,您可以从本地硬盘驱动器加载证书。您需要将私钥包含在证书文件中或指定为密钥文件。如果在您的环境中可能的话,您还需要进行主机验证。请参阅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()
于 2016-02-03T09:28:10.690 回答