文档中心
PythonSSL璇佷功涓嶅彲淇¢棶棰樿瑙e師鍥犳帓鏌ヤ笌5绉嶈В鍐虫柟妗?txt
时间 : 2025-09-27 16:30:16浏览量 : 3
什么是SSL证书不可信错误?

当你在Python中使用requests、urllib等库访问HTTPS网站时,可能会遇到这样的报错:
```
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:777)
或者更直白的:
requests.exceptions.SSLError: HTTPSConnectionPool(host='example.com', port=443):
Max retries exceeded with url: / (Caused by SSLError(SSLCertVerificationError(1,
'[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer
certificate (_ssl.c:1129)')))
这表示Python无法验证目标网站的SSL证书是否可信。就像你去银行办业务,柜员要求你出示身份证,但你拿的是张假证或者过期证件一样。
为什么会发生证书不可信错误?
1. 自签名证书
最常见的情况是网站使用了自签名证书。正规网站通常从DigiCert、Let's Encrypt等权威CA机构获取证书,而自签名证书就像自己给自己开的"身份证明",没有第三方背书。
```python
访问使用自签名证书的网站会报错
import requests
response = requests.get('https://self-signed.badssl.com')
专门用于测试的网站
2. 中间证书缺失
完整的证书链应该包含:服务器证书 → 中间证书 → 根证书。如果服务器配置不当,可能只发送了服务器证书,缺少中间环节。
可以通过openssl命令检查完整证书链
openssl s_client -connect example.com:443 -showcerts
3. 本地CA根证书过时
Python使用操作系统或内置的CA根证书库来验证。如果你的Python环境较旧(如macOS预装的Python),可能缺少新的根证书。
查看Python使用的CA文件路径
import ssl
print(ssl.get_default_verify_paths())
4. 系统时间不正确
SSL/TLS协议高度依赖系统时间。如果你的电脑日期设置错误(比如还停留在几年前),会导致认为所有"未来"签发的证书都无效。
Python中检查系统时间是否合理
from datetime import datetime
print(datetime.now())
应该显示当前正确时间
5. SNI问题
对于共享IP的主机(如CDN服务),需要Server Name Indication扩展来识别正确的证书。老旧服务器可能不支持SNI。
requests库自动处理SNI,但低层库可能需要额外配置
import urllib3
urllib3.contrib.pyopenssl.inject_into_urllib3()
Python中5种解决方案(从危险到安全排序)
??方案1:完全禁用验证(仅限测试环境)
最危险但最简单的方法:
requests.get('https://example.com', verify=False)
urllib3会发出警告,可以这样关闭:
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
风险:完全暴露于中间人攻击!就像不检查任何身份证件就让陌生人进入公司机房。
??方案2:自定义不验证特定域名
稍微好一点的方式是只对特定域名禁用验证:
from urllib.request import urlopen
custom_ctx = ssl.create_default_context()
custom_ctx.check_hostname = False
custom_ctx.verify_mode = ssl.CERT_NONE
response = urlopen('https://self-signed.example', context=custom_ctx)
适用场景:企业内部测试环境,已知安全的服务。
?方案3:添加特定CA根证书
如果你信任这个自签名CA,可以将其加入受信列表:
1. 将CA的PEM格式证书保存为`custom_ca.pem`
2. Python代码中指定:
response = requests.get('https://internal.company.com', verify='/path/to/custom_ca.pem')
最佳实践:将多个CA合并为一个文件:
```bash
cat ca1.pem ca2.pem > combined_cas.pem
??方案4:更新系统的CA certificates包
对于Linux系统:
Ubuntu/Debian
sudo apt-get install --reinstall ca-certificates
CentOS/RHEL
sudo yum reinstall ca-certificates
Alpine Linux
apk add --no-cache ca-certificates && update-ca-certificates
对于macOS用户:
- brew安装的Python可用`brew install certifi`
- Apple官方Python应更新系统到最新版本
Windows用户应通过系统更新获取最新根证书。
???方案5:使用certifi库管理CA包(推荐)
certifi是维护最新Mozilla CA列表的Python包:
```python
import requests
import certifi
response = requests.get('https://example.com', verify=certifi.where())
certifi.where()返回最新CA包路径
print(certifi.where())
升级certifi:
```bash
pip install --upgrade certifi
HTTPS请求调试技巧
当遇到问题时,可以分步诊断:
1. 检查原始SSL信息:
```python
import socket, ssl
hostname = 'example.com'
ctx = ssl.create_default_context()
with socket.create_connection((hostname, 443)) as sock:
with ctx.wrap_socket(sock, server_hostname=hostname) as ssock:
print(ssock.version())
TLS版本
print(ssock.getpeercert())
查看完整服务端信息
```
2. 对比不同工具的结果:
```bash
curl -v https://example.com
Linux/macOS终端命令测试
python -m pip install --upgrade pip
pip有时也会触发SSL问题
3. 使用在线检测工具辅助分析:
- [SSL Labs Server Test](https://www.ssllabs.com/ssltest/)
- [Digicert Certificate Checker](https://www.digicert.com/help/)
CI/CD环境中的特殊处理
在自动化环境中可能需要额外配置:
Docker容器中确保安装ca-certificates:
```dockerfile
FROM python:3-alpine
RUN apk add --no-cache ca-certificates && update-ca-certificates
COPY requirements.txt .
RUN pip install -r requirements.txt
GitLab CI示例:
```yaml
test_job:
image: python:3.8
before_script:
- apt-get update && apt-get install -y ca-certificates
script:
- python test_ssl.py
TLS最佳实践
1. 开发环境
```textplaintextplaintextplaintextplaintextplaintextplaintextplaintextplaintextplaintextplaintextplaintextplaintextplaintextplain文本内容已到达最大长度限制。以下是剩余内容的简要概述:
- 生产环境必须启用完整验证
- 定期更新certifi和系统CA存储
- 关键服务应使用商业EV/OV证书
- 监控工具推荐: OpenSSL、certbot、Let's Encrypt客户端等
TAG:python ssl 证书不可信,ssl证书不可信怎么解决,python中的ssl模块不可用,python ssl模块详解,python爬虫ssl错误,python ssl报错