ssl新闻资讯

文档中心

PythonSSL璇佷功瑙f瀽瀹炴垬浠庡師鐞嗗埌浠g爜瀹炵幇

时间 : 2025-09-27 16:30:18浏览量 : 2

SSL证书基础概念

2PythonSSL璇佷功瑙f瀽瀹炴垬浠庡師鐞嗗埌浠g爜瀹炵幇

SSL/TLS证书是互联网安全通信的基石,它就像网站的"身份证"。当你在浏览器地址栏看到那个小锁图标时,说明当前连接使用了SSL加密。让我们用一个生活中的例子来理解:

想象你要给朋友寄一封重要信件。普通HTTP就像用明信片寄送 - 任何人都能看到内容。而HTTPS(HTTP+SSL)则像是把信放进保险箱,只有你和朋友有钥匙能打开。

SSL证书主要包含以下关键信息:

- 颁发给谁(Common Name):比如www.example.com

- 颁发者(Issuer):如Let's Encrypt、DigiCert等CA机构

- 有效期:证书不是永久有效的

- 公钥:用于加密通信的密钥对中的公开部分

Python中的SSL模块

Python内置的ssl模块提供了丰富的SSL/TLS功能。我们先来看一个最简单的例子 - 获取网站证书:

```python

import ssl

import socket

def get_certificate(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:

return ssock.getpeercert()

示例:获取百度的证书信息

cert_info = get_certificate("www.baidu.com")

print(cert_info)

```

运行这段代码,你会看到一个包含百度SSL证书信息的字典。但输出的内容可能看起来有些杂乱,我们需要进一步解析。

深入解析证书内容

让我们改进上面的代码,提取更有价值的信息:

from datetime import datetime

def parse_certificate(cert):

"""解析证书信息"""

print("颁发给:", cert.get('subject'))

print("颁发者:", cert.get('issuer'))

处理有效期

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

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

print(f"有效期: {not_before} 至 {not_after}")

SANs(主题备用名称)

for extension in cert.get('subjectAltName', []):

print(f"备用名称: {extension[0]} - {extension[1]}")

使用之前的函数获取证书后解析

parse_certificate(cert_info)

这个改进版本会输出更结构化的信息。你可能注意到有些字段如'subject'和'issuer'还是不太易读,因为它们是以元组列表的形式存储的。

处理X.509证书格式

实际上,Python返回的是已经解码的证书信息。如果要直接处理原始X.509证书,我们可以使用cryptography库:

from cryptography import x509

from cryptography.hazmat.backends import default_backend

def parse_x509_certificate(pem_data):

"""解析X.509格式证书"""

cert = x509.load_pem_x509_certificate(pem_data, default_backend())

print("版本:", cert.version)

print("序列号:", cert.serial_number)

subject = cert.subject

print("\n主题信息:")

for attr in subject:

print(f"{attr.oid._name}: {attr.value}")

issuer = cert.issuer

print("\n颁发者信息:")

for attr in issuer:

print("\n有效期:")

print(f"生效时间: {cert.not_valid_before}")

print(f"过期时间: {cert.not_valid_after}")

print("\n扩展信息:")

for ext in cert.extensions:

if ext.oid.dotted_string == '2.5.29.17':

SAN扩展

names = ext.value.get_values_for_type(x509.DNSName)

print("SANs:", ", ".join(names))

SSL验证的重要性

在实际应用中,仅仅获取证书是不够的,验证其有效性才是关键。Python默认会验证主机名和信任链:

def verify_certificate(hostname):

context = ssl.create_default_context()

try:

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

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

cert = ssock.getpeercert()

return True, "验证通过"

except ssl.CertificateError as e:

return False, f"证书错误: {e}"

except ssl.SSLError as e:

return False, f"SSL错误: {e}"

常见的验证失败原因包括:

1. 自签名证书(没有受信任的CA签发)

2. 主机名不匹配(访问example.com但证书是给*.example.org的)

3. 过期或未生效的证书

4. CA根证书不在系统信任库中

OpenSSL命令行对比

熟悉OpenSSL命令行的同学可能会问:Python实现和OpenSSL命令有什么区别?让我们对比一下:

OpenSSL方式:

openssl s_client -connect www.example.com:443 -showcerts

Python方式的优势:

1. 可编程性:可以集成到自动化工具中

2. 灵活性:可以自定义验证逻辑和处理流程

3. 跨平台:不需要依赖系统OpenSSL版本

PyOpenSSL高级用法

对于更高级的需求,PyOpenSSL提供了更多功能:

from OpenSSL import SSL, crypto

def check_crl(cert_pem):

"""检查CRL(吊销列表)"""

cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert_pem)

x509 = X509.load_cert_string(cert_pem)

TODO: CRL检查逻辑...

return True

def verify_ocsp(cert_pem):

"""OCSP在线状态检查"""

TODO: OCSP检查逻辑...

这些高级检查可以帮助发现已被吊销但未过期的可疑证书。

HTTPS请求时的注意事项

在使用requests等库发起HTTPS请求时,了解背后的SSL验证很重要:

import requests

??危险示范(禁用验证)

requests.get('https://expired.badssl.com', verify=False)

?正确做法(自定义CA包)

requests.get('https://example.com', verify='/path/to/custom/ca-bundle.crt')

?另一种正确做法(严格主机名验证)

session = requests.Session()

session.mount('https://', requests.adapters.HTTPAdapter(

max_retries=3,

assert_hostname=True,

assert_fingerprint='sha256指纹...'

))

在生产环境中禁用verify=False是非常危险的中间人攻击漏洞!

SSL/TLS最佳实践

1. 定期检查:监控所有服务的到期时间(可以用我们写的脚本自动化)

2. 最小权限:私钥文件应设置严格的访问权限

3. 及时更新:关注TLS协议漏洞(如POODLE、Heartbleed)

4. 强化配置:禁用老旧协议和弱密码套件

以下是一个简单的到期监控脚本示例:

```python

import smtplib

from email.mime.text import MIMEText

def check_expiry_and_alert(domains):

for domain in domains:

certs_left_days = (cert['notAfter'] - datetime.now()).days

if certs_left_days < threshold_days:

send_expiry_alert(domain)

def send_expiry_alert(domain):

msg_text = f"{domain} SSL将在{certs_left_days}天后过期!"

try:

smtp.sendmail(from_addr="monitor@example.com", to_addrs=["admin@example.com"], msg=msg_text.as_string())

except Exception as e:

logging.error(f"邮件发送失败:{e}")

if __name__ == '__main__':

tracked_domains = ["www.example.com", "api.example.com"]

while True:

check_expiry_and_alert(tracked_domains)

time.sleep(86400)

每天检查一次

通过本文的学习,你应该已经掌握了使用Python处理和解析SSL/TLS的核心技能。记住在实际应用中要特别注意安全性问题!

TAG:python ssl 证书 解析,python3 ssl,python ssl module,pythonssl证书验证错误,python项目的ssl证书怎么配