ssl新闻资讯

文档中心

Python瀹炴垬3鍒嗛挓鏁欎綘鐢ㄤ唬鐮佺敓鎴怱SL璇佷功锛堥檮瀹屾暣绀轰緥锛?txt

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

2Python瀹炴垬3鍒嗛挓鏁欎綘鐢ㄤ唬鐮佺敓鎴怱SL璇佷功锛堥檮瀹屾暣绀轰緥锛?txt

SSL证书是网络安全的基础设施之一,它就像网站的"身份证",确保用户访问的是真实可信的网站。作为开发者,我们经常需要在开发环境或内部系统中使用SSL证书。本文将手把手教你用Python快速生成自签名SSL证书,并深入解析背后的密码学原理。

一、SSL证书的基本原理

想象一下你要给朋友寄一封机密信件。SSL/TLS协议就像:

1. 一个防篡改信封(加密)

2. 一份带印章的授权书(证书验证)

3. 只有收件人知道的解码手册(密钥交换)

常见的证书类型包括:

- DV证书(域名验证):就像简易名片

- OV证书(组织验证):类似带公章的工作证

- EV证书(扩展验证):好比需要面签的护照

二、Python生成证书的4种方法

方法1:使用cryptography库(推荐)

```python

from cryptography import x509

from cryptography.x509.oid import NameOID

from cryptography.hazmat.primitives import hashes, serialization

from cryptography.hazmat.primitives.asymmetric import rsa

import datetime

生成私钥

private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)

构建证书信息

subject = issuer = x509.Name([

x509.NameAttribute(NameOID.COUNTRY_NAME, "CN"),

x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "Beijing"),

x509.NameAttribute(NameOID.LOCALITY_NAME, "Beijing"),

x509.NameAttribute(NameOID.ORGANIZATION_NAME, "My Company"),

x509.NameAttribute(NameOID.COMMON_NAME, "mysite.com"),

])

cert = x509.CertificateBuilder().subject_name(

subject

).issuer_name(

issuer

).public_key(

private_key.public_key()

).serial_number(

x509.random_serial_number()

).not_valid_before(

datetime.datetime.now(datetime.timezone.utc)

).not_valid_after(

datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(days=365)

).add_extension(

x509.SubjectAlternativeName([x509.DNSName("localhost")]),

critical=False,

).sign(private_key, hashes.SHA256())

保存证书和私钥

with open("certificate.pem", "wb") as f:

f.write(cert.public_bytes(serialization.Encoding.PEM))

with open("private_key.pem", "wb") as f:

f.write(private_key.private_bytes(

encoding=serialization.Encoding.PEM,

format=serialization.PrivateFormat.TraditionalOpenSSL,

encryption_algorithm=serialization.NoEncryption()

))

```

方法2:使用OpenSSL命令行封装

import subprocess

def generate_cert(domain="localhost", days=365):

subprocess.run([

"openssl", "req", "-x509", "-newkey", "rsa:4096",

"-keyout", "key.pem", "-out", "cert.pem",

"-days", str(days), "-nodes",

"-subj", f"/CN={domain}"

], check=True)

generate_cert()

方法3:使用pyOpenSSL库

from OpenSSL import crypto

key = crypto.PKey()

key.generate_key(crypto.TYPE_RSA, 2048)

cert = crypto.X509()

cert.get_subject().CN = "localhost"

cert.set_serial_number(1000)

cert.gmtime_adj_notBefore(0)

cert.gmtime_adj_notAfter(365*24*60*60)

cert.set_issuer(cert.get_subject())

cert.set_pubkey(key)

cert.sign(key, 'sha256')

open("certificate.crt", "wb").write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert))

open("private.key", "wb").write(crypto.dump_privatekey(crypto.FILETYPE_PEM, key))

方法4:使用M2Crypto库

from M2Crypto import X509, RSA, EVP

pk = RSA.gen_key(2048, 65537)

cert = X509.X509()

cert.set_version(2)

cert.set_serial_number(1)

name = X509.X509_Name()

name.CN = "localhost"

name.O = "My Org"

name.OU = "My Unit"

name.C = "CN"

cert.set_subject(name)

cert.set_issuer(name)

pubkey = EVP.PKey()

pubkey.assign_rsa(pk)

cert.set_pubkey(pubkey)

import time

now = int(time.time())

now_str = time.strftime("%Y%m%d%H%M%SZ", time.gmtime(now))

expire_str = time.strftime("%Y%m%d%H%M%SZ", time.gmtime(now + 365*24*60*60))

from M2Crypto import ASN1

now_asn1 = ASN1.ASN1_UTCTIME()

now_asn1.set_string(now_str)

expire_asn1 = ASN1.ASN1_UTCTIME()

expire_asn1.set_string(expire_str)

cert.set_not_before(now_asn1)

cert.set_not_after(expire_asn1)

cert.sign(pubkey, 'sha256')

open("my.crt","w").write(cert.as_pem())

open("my.key","w").write(pk.as_pem(None))

三、生产环境注意事项

虽然自签名证书适合开发和测试,但在生产环境中需要注意:

1. 浏览器警告问题:自签名证书会被标记为"不安全"

- Chrome会显示红色警告页

- Firefox会提示安全风险

2. 有效期管理

```python

自动检查过期时间示例

from cryptography import x509

with open("certificate.pem", "rb") as f:

cert_data = f.read()

cert = x509.load_pem_x509_certificate(cert_data)

if cert.not_valid_after < datetime.datetime.now():

print("?? 证书已过期!")

```

3. 密钥安全存储

AES加密私钥示例

from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC

password = b"strong_password"

salt = os.urandom(16)

kdf = PBKDF2HMAC(

algorithm=hashes.SHA256(),

length=32,

salt=salt,

iterations=100000,

)

key_for_storage(private_key, password="password")

四、进阶技巧:CA链式签发

如果需要模拟更真实的CA签发过程:

CA根证书生成示例(简化版)

ca_key = rsa.generate_private_key(public_exponent=65537, key_size=4096)

ca_cert_builder.subject_name(subject)\...

ca_cert_builder.add_extensions([

CA基础约束扩展非常重要!

BasicConstraints(ca=True, path_length=None),

KeyUsage(...),

ca_cert_builder.sign(...)

然后用CA签发终端实体证书:

builder.add_extensions([

AuthorityKeyIdentifier.from_issuer_subject_key_id(...),

builder.sign(private_key=ca_key,...)

五、常见问题解答

Q:为什么我的Python服务使用自签名证书报错?

A:常见原因有:

- SAN扩展缺失(现代浏览器要求)→添加`SubjectAlternativeName`

- SHA-1签名算法不安全→改用SHA-256/384

- RSA密钥长度不足→至少2048位

Q:如何让Python请求忽略SSL验证?

A:(仅限测试环境)

```python

import requests

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

或者创建自定义适配器:

session.mount('https://', SSLAdapter())

Q:如何查看生成的证书详情?

A:使用OpenSSL命令:

openssl x509 -in certificate.pem -text -noout

或Python解析:

print(f"颁发给: {cert.subject.rfc4514_string()}")

print(f"有效期至: {str(cert.not_valid_after)}")

print(f"指纹: {binascii.b2a_base64(cert.fingerprint(...))}")

掌握这些技能后,你就能在开发中灵活应对各种HTTPS需求了!记得生产环境还是要使用受信任CA签发的正式证书哦。

TAG:python 生成 ssl证书,python ssl认证,python ssl certificate,python项目的ssl证书怎么配,pythonssl证书验证错误,python获取ssl证书信息