ssl新闻资讯

文档中心

Python涓嬭浇绔欑偣SSL璇佷功鍏ㄦ敾鐣ヤ粠鍘熺悊鍒板疄鎴樹唬鐮佺ず渚?txt

时间 : 2025-09-27 16:30:20浏览量 : 1

2Python涓嬭浇绔欑偣SSL璇佷功鍏ㄦ敾鐣ヤ粠鍘熺悊鍒板疄鎴樹唬鐮佺ず渚?txt

SSL证书是保障网站数据传输安全的核心要素,对于Python开发者来说,掌握如何通过代码下载和分析SSL证书是一项实用技能。本文将带你深入理解SSL证书的工作原理,并通过多个Python代码示例展示如何从任意网站获取SSL证书信息。

一、SSL证书基础:网站的"身份证"

想象一下SSL证书就像是网站的身份证。当你在浏览器访问https://开头的网站时,浏览器会先检查这个"身份证"是否真实有效。这张"身份证"包含三个关键信息:

1. 网站身份信息:就像身份证上有你的姓名和照片一样,SSL证书包含网站的域名、公司名称等信息

2. 颁发机构:如同公安局签发你的身份证,SSL证书由受信任的CA机构(如Let's Encrypt、DigiCert)签发

3. 有效期:和身份证一样有使用期限

举个例子,当你访问https://github.com时:

- 浏览器会收到GitHub服务器的SSL证书

- 检查是否由可信CA签发

- 核对证书中的域名是否匹配

- 确认证书在有效期内

只有全部验证通过,才会建立安全连接。否则你会看到类似"您的连接不是私密连接"的警告。

二、Python获取SSL证书的4种方法

方法1:使用ssl模块获取原始证书

```python

import ssl

import socket

from pprint import pprint

def get_ssl_cert(hostname, port=443):

创建SSL上下文

context = ssl.create_default_context()

建立连接并获取证书

with socket.create_connection((hostname, port)) as sock:

with context.wrap_socket(sock, server_hostname=hostname) as ssock:

cert = ssock.getpeercert()

return cert

示例:获取GitHub的SSL证书

cert_info = get_ssl_cert("github.com")

pprint(cert_info)

```

这段代码会输出类似这样的信息:

{'issuer': ((('countryName', 'US'),),

(('organizationName', 'DigiCert Inc'),),

(('organizationalUnitName', 'www.digicert.com'),),

(('commonName', 'DigiCert SHA2 High Assurance Server CA'),)),

'notAfter': 'Mar 8 12:00:00 2025 GMT',

'notBefore': 'Mar 5 00:00:00 2025 GMT',

'serialNumber': '0E2E4B0CFFA9B1B5D5F7D3A0E9F8B7D2',

...}

方法2:使用requests库简化流程

import requests

from ssl import SSLContext

def get_cert_via_requests(url):

response = requests.get(url, verify=True)

cert = response.connection.sock.getpeercert()

示例用法

cert = get_cert_via_requests("https://python.org")

print(f"Python官网证书有效期至: {cert['notAfter']}")

方法3:保存PEM格式的完整证书链

有时我们需要将整个证书链保存为文件进行分析:

def save_full_cert_chain(hostname, filename="certificate.pem"):

cert_pem = ssl.get_server_certificate((hostname, 443))

with open(filename, "w") as f:

f.write(cert_pem)

print(f"已保存 {hostname} 的完整证书到 {filename}")

保存百度首页的SSL证书

save_full_cert_chain("www.baidu.com", "baidu_cert.pem")

方法4:高级应用 - OpenSSL命令行集成

对于需要更深度分析的情况,可以结合OpenSSL命令行工具:

import subprocess

def check_cert_with_openssl(hostname):

cmd = f"openssl s_client -connect {hostname}:443 -showcerts

result = subprocess.run(cmd, shell=True, capture_output=True, text=True)

if result.returncode == 0:

print(result.stdout)

else:

print("执行出错:", result.stderr)

OpenSSL方式检查淘宝网证书链

check_cert_with_openssl("www.taobao.com")

三、实战案例解析:验证电商网站安全性

假设我们要开发一个监控电商网站安全性的脚本:

from datetime import datetime

def check_ecommerce_site(domain):

try:

cert = get_ssl_cert(domain)

SSL有效期检查(剩余天数)

expiry_date = datetime.strptime(cert['notAfter'], '%b %d %H:%M:%S %Y %Z')

days_left = (expiry_date - datetime.now()).days

HTTPS配置评分(满分100)

score = min(days_left * (1 if days_left >30 else -1),

100 if len(cert.get('subjectAltName', [])) >0 else

(80 if "CN=" in str(cert['subject']) else

60))

print(f"{domain}安全检查结果:")

print(f"- SSL剩余有效期: {days_left}天")

print(f"- HTTPS配置评分: {score}/100")

if days_left <15:

print("??警告: SSL即将过期!")

except Exception as e:

print(f"{domain}检测失败:", str(e))

JD.COM的安全检查

check_ecommerce_site("www.jd.com")

输出可能类似于:

www.jd.com安全检查结果:

- SSL剩余有效期: 87天

- HTTPS配置评分: 87/100

四、常见问题与解决方案(Q&A)

Q1: Python下载的SSL信息和浏览器看到的不一致?

A: Python默认只验证服务器发送的第一个终端实体(end-entity)证书。要获取完整链需要额外处理:

```python

def get_full_chain(hostname):

context = ssl.SSLContext()

conn = context.wrap_socket(socket.socket(), server_hostname=hostname)

conn.connect((hostname,443))

DER格式转为PEM格式

pem_data = []

for der in conn.getpeercert(binary_form=True) or []:

pem_data.append(

"--BEGIN CERTIFICATE--\n" +

"\n".join(textwrap.wrap(base64.b64encode(der).decode(),64)) +

"\n--END CERTIFICATE--\n"

)

return pem_data

finally:

conn.close()

chain_jd = get_full_chain("www.jd.com")[0]

JD根CA通常是第一个

Q2: Python报错`ssl.SSLCertVerificationError`怎么处理?

这通常意味着:

1. CA根不在系统信任库中(自签名或内部CA)

2. CN/SAN不匹配当前域名

临时解决方案(仅限测试环境):

context.verify_mode = ssl.CERT_NONE

??禁用验证(不安全)

生产环境正确做法是添加自定义CA包:

context.load_verify_locations("/path/to/custom/ca-bundle.crt")

五、进阶技巧与最佳实践

TLS指纹识别技术

某些安全设备会通过TLS握手特征识别客户端类型:

def spoof_firefox_tls():

ctx = ssl.SSLContext()

ctx.set_alpn_protocols(["h2", "http/1.1"])

Firefox支持的ALPN协议

ctx.options |= (

ssl.PROTOCOL_TLS |

TLSv1+协议族

ssl.PROTOCOL_TLSv1 |

TLSv1.x兼容性

ssl.PROTOCOL_TLSv1_2

Firefox默认TLS版本

)

ciphers="TLS_AES...CHACHA..."

Firefox特有密码套件列表

ctx.set_ciphers(ciphers)

return ctx

with requests.Session() as sess:

sess.mount("https://", MyAdapter(ctx))

HTTP请求时模拟Firefox指纹

OCSP装订状态检查

在线验证吊销状态比CRL更高效:

from cryptography.x509 import ocsp

async def check_revocation(url):

builder = ocsp.OCSPRequestBuilder()

builder.add_by_url(url)

req_bytes=builder.build().public_bytes(...)

async with aiohttp.ClientSession() as sess:

resp=await sess.post(

"http://ocsp.digicert.com",

data=req_bytes,

headers={"Content-Type":"application/ocsp-request"}

)

return ocsp.load_response(resp.content).status == ocsp.VALID

```

> 专业提示:生产环境中建议使用`pyOpenSSL`或`cryptography`等专业库替代标准库ssl模块,它们提供更完整的X509处理能力。

六、与资源推荐

本文介绍的技术可应用于以下场景:

?自动化HTTPS监控系统开发

?爬虫绕过WAF指纹检测

?企业内部PKI管理工具开发

扩展学习资源推荐:

??《Bulletproof SSL and TLS》(Ivan Risti?著) - SSL/TLS圣经级著作

?? Let's Encrypt文档 - https://letsencrypt.org/docs/

TAG:python下载站点ssl证书,python网站下载,the ssl module in python is,python中的ssl模块不能用,python ssl certificate,python下载链接