如何获取HTTPS服务器响应的签名摘要?(Python实现咨询)
嘿,这个需求我刚好处理过,用Python完全可以实现!我们分两种方式来做,一种是用标准库直接操作SSL连接,另一种是结合大家常用的requests库,都能拿到你要的响应、SSL证书和服务器签名的消息摘要,下面详细说明:
方案一:使用标准库(ssl + http.client)
这种方式更贴近底层,能直接获取SSL连接的所有细节,只需要额外安装cryptography库用来解析证书。
首先先安装依赖:
pip install cryptography
然后看代码示例,我加了详细注释:
import ssl import http.client from cryptography import x509 from cryptography.hazmat.primitives import hashes # 替换成你要请求的目标服务器 TARGET_HOST = "example.com" TARGET_PORT = 443 # 创建默认的SSL上下文(包含系统信任的根证书) ssl_context = ssl.create_default_context() # 建立HTTPS连接 conn = http.client.HTTPSConnection(TARGET_HOST, TARGET_PORT, context=ssl_context) # 发送GET请求 conn.request("GET", "/") # 获取Response对象,这部分和普通请求一样 response = conn.getresponse() print("=== 响应信息 ===") print(f"状态码: {response.status}") print(f"响应头: {dict(response.getheaders())}") print(f"响应体: {response.read().decode('utf-8')}\n") # 获取SSL证书(二进制DER格式) der_certificate = conn.sock.getpeercert(binary_form=True) # 解析证书为可操作的对象 cert = x509.load_der_x509_certificate(der_certificate) # 打印证书基本信息 print("=== SSL证书详情 ===") print(f"证书主题: {cert.subject}") print(f"证书颁发者: {cert.issuer}") print(f"有效期起始: {cert.not_valid_before}") print(f"有效期结束: {cert.not_valid_after}\n") # 获取服务器签名的消息摘要(这里指证书的SHA256指纹,以及签名相关信息) signature_algo = cert.signature_algorithm_oid._name cert_sha256_fingerprint = cert.fingerprint(hashes.SHA256()).hex() cert_signature_value = cert.signature.hex() print("=== 服务器签名相关信息 ===") print(f"签名算法: {signature_algo}") print(f"证书SHA256指纹(消息摘要): {cert_sha256_fingerprint}") print(f"证书原始签名值: {cert_signature_value}") # 别忘了关闭连接 conn.close()
方案二:使用requests库(自定义适配器)
如果你平时习惯用requests,可以通过自定义适配器来捕获SSL连接后的证书信息,用法更符合日常开发习惯。
同样需要先安装cryptography,然后看代码:
import requests from requests.adapters import HTTPAdapter from urllib3.poolmanager import PoolManager import ssl from cryptography import x509 from cryptography.hazmat.primitives import hashes # 自定义适配器,用来捕获SSL证书 class SSLInfoAdapter(HTTPAdapter): def init_poolmanager(self, *args, **kwargs): # 创建SSL上下文 ssl_context = ssl.create_default_context() # 用来存储解析后的证书 self.parsed_cert = None # 定义握手完成后的回调函数,获取证书 def post_handshake_callback(conn): der_cert = conn.getpeercert(binary_form=True) self.parsed_cert = x509.load_der_x509_certificate(der_cert) # 绑定回调到上下文 ssl_context.set_post_handshake_callback(post_handshake_callback) kwargs['ssl_context'] = ssl_context return super().init_poolmanager(*args, **kwargs) # 创建session并挂载自定义适配器 session = requests.Session() ssl_adapter = SSLInfoAdapter() session.mount('https://', ssl_adapter) # 发送GET请求 response = session.get("https://example.com") # 打印响应信息 print("=== 响应信息 ===") print(f"状态码: {response.status_code}") print(f"响应头: {dict(response.headers)}") print(f"响应体: {response.text}\n") # 提取证书和签名信息 if ssl_adapter.parsed_cert: print("=== SSL证书详情 ===") print(f"证书主题: {ssl_adapter.parsed_cert.subject}") print(f"证书颁发者: {ssl_adapter.parsed_cert.issuer}\n") print("=== 服务器签名相关信息 ===") print(f"签名算法: {ssl_adapter.parsed_cert.signature_algorithm_oid._name}") print(f"证书SHA256指纹(消息摘要): {ssl_adapter.parsed_cert.fingerprint(hashes.SHA256()).hex()}") print(f"证书原始签名值: {ssl_adapter.parsed_cert.signature.hex()}")
补充说明
如果这里的“服务器签名的消息摘要”指的是响应体的签名(比如部分API会在响应头里附带响应体的签名值),那你需要从响应头中提取对应的签名字段(比如X-Signature),然后用服务器的公钥验证这个签名对应的摘要。这种情况需要结合具体API的文档来处理,上面的代码主要针对SSL证书相关的签名摘要。
内容的提问来源于stack exchange,提问作者Michael Wild
相关产品推荐
相关产品推荐

