如何获取被TLS检查代理篡改前的服务器证书颁发者名称?
获取未被代理篡改的原始TLS证书颁发者名称(Python实现)
组织代理的TLS中间人攻击会篡改服务器证书,要拿到原始证书的颁发者信息,核心思路是绕过代理直接与目标服务器建立SSL连接——因为篡改行为发生在代理层,直连服务器就能获取到未被修改的原始证书。
纯SSL模块实现(无第三方依赖)
import ssl import socket def get_original_cert_issuer(hostname, port=443): # 直接创建TCP socket,绕过系统代理 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(10) try: sock.connect((hostname, port)) # 创建SSL上下文,禁用证书验证(避免代理篡改后的证书导致验证失败) context = ssl.create_default_context() context.check_hostname = False context.verify_mode = ssl.CERT_NONE # 建立SSL连接,指定server_hostname支持SNI with context.wrap_socket(sock, server_hostname=hostname) as ssock: cert = ssock.getpeercert() # 解析证书颁发者字段 issuer = dict(item[0] for item in cert['issuer']) # 格式化返回常见的颁发者信息(组织名+通用名) return f"组织名: {issuer.get('organizationName', '未知')}, 通用名: {issuer.get('commonName', '未知')}" except Exception as e: return f"错误: {str(e)}" finally: sock.close() # 测试示例 if __name__ == "__main__": target = "google.com" print(f"{target} 的原始证书颁发者:\n{get_original_cert_issuer(target)}")
Requests库实现(更简洁)
如果习惯用Requests库,需要禁用系统代理并自定义SSL适配器:
import requests from requests.adapters import HTTPAdapter from urllib3.poolmanager import PoolManager import ssl class NoProxySSLAdapter(HTTPAdapter): def init_poolmanager(self, connections, maxsize, block=False): # 配置不验证证书的SSL上下文 ctx = ssl.create_default_context() ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE self.poolmanager = PoolManager(num_pools=connections, maxsize=maxsize, block=block, ssl_context=ctx) def get_issuer_via_requests(hostname): session = requests.Session() # 禁用系统代理,强制直连 session.trust_env = False # 挂载自定义适配器 session.mount("https://", NoProxySSLAdapter()) try: resp = session.get(f"https://{hostname}", timeout=10) cert = resp.connection.sock.getpeercert() issuer = dict(item[0] for item in cert['issuer']) return f"组织名: {issuer.get('organizationName', '未知')}, 通用名: {issuer.get('commonName', '未知')}" except Exception as e: return f"错误: {str(e)}" # 测试示例 if __name__ == "__main__": print(get_issuer_via_requests("github.com"))
关键注意事项
- 确认你的网络允许直连目标服务器:部分组织会强制所有流量走代理,禁止直连,这种情况下该方法无法生效。
- 代码禁用了证书验证:仅用于获取原始证书信息,不要用在实际业务请求中,避免安全风险。
- 支持SNI:对于使用SNI的多域名服务器,必须指定
server_hostname参数,否则会拿到错误的证书。
内容的提问来源于stack exchange,提问作者sheshu N
相关产品推荐
相关产品推荐

