Python如何通过SSLContext加载字节形式证书调用HTTPS API?
可以直接用字节数据加载SSLContext,无需写入文件
方法一:标准库ssl + BytesIO(兼容现有pyOpenSSL代码)
Python 3.7+ 的ssl.SSLContext方法支持接受类文件对象作为参数,你可以用io.BytesIO将crypto.dump_*得到的字节数据包装成类文件对象,直接传给加载方法:
import io import ssl from OpenSSL import crypto # 从PKCS12获取证书、私钥、CA证书的字节数据 cert_bytes = crypto.dump_certificate(crypto.FILETYPE_PEM, keystore_pkcs12.get_certificate()) key_bytes = crypto.dump_privatekey(crypto.FILETYPE_PEM, keystore_pkcs12.get_privatekey()) # 若有多个CA证书,可将多个PEM字节拼接后传入 ca_bytes = crypto.dump_certificate(crypto.FILETYPE_PEM, truststore_pkcs12.get_ca_certificates()[0]) # 构建SSLContext并加载字节形式的证书 context = ssl.SSLContext(ssl.PROTOCOL_TLS) # 加载证书链和私钥 context.load_cert_chain( certfile=io.BytesIO(cert_bytes), keyfile=io.BytesIO(key_bytes) # 若私钥有密码,添加 password=b"your_key_password" 参数 ) # 加载CA证书用于验证 context.load_verify_locations(cafile=io.BytesIO(ca_bytes)) # 建立HTTPS连接 self.connection = http.client.HTTPSConnection(host=HOST, port=PORT, context=context)
方法二:使用cryptography库(推荐,替代pyOpenSSL)
pyOpenSSL已停止维护,cryptography是Python官方推荐的加密库,API更现代清晰:
- 先安装库:
pip install cryptography
- 示例代码:
import io import ssl from cryptography.hazmat.primitives import serialization from cryptography.hazmat.backends import default_backend # 从PKCS12加载证书、私钥(若从文件加载PKCS12) # with open("keystore.p12", "rb") as f: # pkcs12 = serialization.pkcs12.load_pkcs12( # f.read(), # password=b"your_pkcs12_password", # backend=default_backend() # ) # cert = pkcs12.certificate # private_key = pkcs12.private_key # 假设你已从PKCS12获取到对应对象,序列化为PEM字节 cert_pem = cert.public_bytes(encoding=serialization.Encoding.PEM) key_pem = private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption() # 若私钥有密码,替换为:serialization.BestAvailableEncryption(b"your_key_password") ) ca_pem = ca_cert.public_bytes(encoding=serialization.Encoding.PEM) # 构建SSLContext context = ssl.SSLContext(ssl.PROTOCOL_TLS) context.load_cert_chain(io.BytesIO(cert_pem), io.BytesIO(key_pem)) context.load_verify_locations(io.BytesIO(ca_pem)) # 建立连接 self.connection = http.client.HTTPSConnection(host=HOST, port=PORT, context=context)
注意事项
- 若私钥受密码保护,需在
load_cert_chain中添加password参数(传入字节形式的密码)。 - 若有多个CA证书,需将所有CA证书的PEM字节拼接成一个字节串后,再传入
load_verify_locations。
内容的提问来源于stack exchange,提问作者Cuong Pham
相关产品推荐
相关产品推荐

