You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Software_Architecture/distance-judgement/tools/generate_ssl_cert.py

97 lines
3.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
生成自签名SSL证书用于HTTPS服务
"""
import os
import datetime
import ipaddress
from cryptography import x509
from cryptography.x509.oid import NameOID
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa
def generate_ssl_certificate():
"""生成自签名SSL证书"""
# 创建ssl目录
ssl_dir = "ssl"
if not os.path.exists(ssl_dir):
os.makedirs(ssl_dir)
print("🔑 正在生成SSL证书...")
# 生成私钥
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, "Distance Judgement System"),
x509.NameAttribute(NameOID.COMMON_NAME, "localhost"),
])
# 生成证书
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.utcnow()
).not_valid_after(
datetime.datetime.utcnow() + datetime.timedelta(days=365)
).add_extension(
x509.SubjectAlternativeName([
x509.DNSName("localhost"),
x509.DNSName("127.0.0.1"),
x509.IPAddress(ipaddress.IPv4Address("127.0.0.1")),
x509.IPAddress(ipaddress.IPv4Address("0.0.0.0")),
]),
critical=False,
).sign(private_key, hashes.SHA256())
# 保存私钥
key_path = os.path.join(ssl_dir, "key.pem")
with open(key_path, "wb") as f:
f.write(private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption()
))
# 保存证书
cert_path = os.path.join(ssl_dir, "cert.pem")
with open(cert_path, "wb") as f:
f.write(cert.public_bytes(serialization.Encoding.PEM))
print(f"✅ SSL证书已生成:")
print(f" 🔑 私钥: {key_path}")
print(f" 📜 证书: {cert_path}")
print(f" 📅 有效期: 365天")
print()
print("⚠️ 注意: 这是自签名证书,浏览器会显示安全警告")
print(" 点击 '高级' -> '继续访问localhost(不安全)' 即可")
if __name__ == "__main__":
try:
generate_ssl_certificate()
except ImportError:
print("❌ 缺少cryptography库正在尝试安装...")
import subprocess
import sys
subprocess.check_call([sys.executable, "-m", "pip", "install", "cryptography"])
print("✅ cryptography库安装完成重新生成证书...")
generate_ssl_certificate()
except Exception as e:
print(f"❌ 生成SSL证书失败: {e}")