CA系统的设计(CA证书生成,吊销,数字签名生成)

CA系统概述

CA认证系统是一种基于公钥密码基础设施(PKI)的信息安全技术,它可以为网络通信双方提供身份认证、数据加密、数字签名等功能。CA认证系统的核心是证书授权机构(CA),它负责为用户(节点)颁发数字证书,证明其身份和公钥的合法性。数字证书是一种包含用户信息和公钥的电子文件,它由CA用私钥签名,可以被其他用户或系统验证。数字证书的有效性由证书吊销列表(CRL)或在线证书状态协议(OCSP)来维护。

服务端(CA证书中心)功能:

1.接受CSR文件申请(申请CA证书的请求)

2.签发CSR文件形成数字证书

3.撤销CA数字证书文件

4.查看CA证书文件

5.CA客户端用户信息增删改查

CA客户端功能:

1.门限密钥的生成与分发

2.生成CSR文件、发送CA证书申请

3.CA证书验证等功能

4.CA证书吊销申请

5.数字签名生成

证书的生成

1.密钥生成

使用RSA模块生成密钥对

复制代码
#生成密钥函数
def generate_cakey(keysize):
    # 生成 CA 密钥对
    private_key = rsa.generate_private_key(
        public_exponent=65537,
        key_size=keysize,
        backend=default_backend()

    )
    ca_private_key = private_key.private_bytes(
        encoding=Encoding.PEM,
        format=PrivateFormat.PKCS8,
        encryption_algorithm=NoEncryption()
    )
    ca_public_key = private_key.public_key().public_bytes(
        encoding=Encoding.PEM,
        format=serialization.PublicFormat.SubjectPublicKeyInfo
    )
    print("生成密钥成功")
    return private_key,ca_private_key,ca_public_key

密钥对的保存和读取

密钥对需要保存为pem格式以便于后续的使用,密钥对的读取也是从pem格式的密钥读取密钥信息

复制代码
def save_key(ca_private_key,ca_public_key):
    # 将私钥保存到文件
    with open('ca_private_key_4.pem', 'wb') as f:
        f.write(ca_private_key)

    # 将公钥保存到文件
    with open('ca_public_key_4.pem', 'wb') as f:
        f.write(ca_public_key)

    # 打印保存的密钥对文件名
    print("key saved successfully -------------------------------")

def load_key(key_path):
    with open(key_path, 'rb') as f:
        ca_key = f.read()

    return ca_key

2.数字证书的签发

因为是数字证书系统,服务端先要生成CA根证书,后签发中间证书给客户端,所以需要生成2组RSA密钥对,即用户公私钥,服务端公私钥,进行一个证书的发放。

复制代码
def generate_ca_certificate(name,province,country,user_private_key_pem, ca_private_key_pem, deadline):
    #加载CA服务端密钥
    ca_private_key = serialization.load_pem_private_key(ca_private_key_pem, password=None, backend=default_backend())
    #加载用户密钥
    user_private_key = serialization.load_pem_private_key(user_private_key_pem, password=None,
                                                          backend=default_backend())
    #生成CA服务端证书
    root_subject = x509.Name([
        x509.NameAttribute(NameOID.COUNTRY_NAME, 'CN'),
        x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, 'Guangxi'),
        x509.NameAttribute(NameOID.LOCALITY_NAME, 'Guangxi'),
        x509.NameAttribute(NameOID.ORGANIZATION_NAME, 'CA'),
        x509.NameAttribute(NameOID.COMMON_NAME, 'CA'),
    ])
    root_issuer = root_subject #颁发者和主题一样

    before_now = datetime.datetime.utcnow()
    if deadline <= before_now:
        raise ValueError("Deadline must be in the future.")

    serial_number = x509.random_serial_number()

    # 根证书
    root_certificate = (
        x509.CertificateBuilder()
            .subject_name(root_subject)
            .issuer_name(root_issuer)
            .public_key(ca_private_key.public_key())
            .serial_number(serial_number)
            .not_valid_before(before_now)
            .not_valid_after(deadline)
            .add_extension(
            x509.BasicConstraints(ca=True, path_length=None), critical=True
        )
            .sign(ca_private_key, hashes.SHA256(), default_backend())
    )

    #生成中间证书
    intermediate_subject = x509.Name([
        x509.NameAttribute(NameOID.COUNTRY_NAME,country),
        x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME,province),
        x509.NameAttribute(NameOID.LOCALITY_NAME,province),
        x509.NameAttribute(NameOID.ORGANIZATION_NAME,name),
        x509.NameAttribute(NameOID.COMMON_NAME,name),
    ])
    intermediate_issuer = root_subject

    intermediate_certificate = (
        x509.CertificateBuilder()
            .subject_name(intermediate_subject)
            .issuer_name(intermediate_issuer)
            .public_key(user_private_key.public_key())
            .serial_number(x509.random_serial_number())
            .not_valid_before(before_now)
            .not_valid_after(deadline)
            .add_extension(
            x509.BasicConstraints(ca=True, path_length=None), critical=True
        )
            .sign(ca_private_key, hashes.SHA256(), default_backend())
    )

    # 转换为 PEM 格式
    root_cert_pem = root_certificate.public_bytes(serialization.Encoding.PEM)
    intermediate_cert_pem = intermediate_certificate.public_bytes(serialization.Encoding.PEM)

    # 私钥导出
    user_private_key_pem = user_private_key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.TraditionalOpenSSL,
        encryption_algorithm=serialization.NoEncryption()
    )
    ca_private_key_pem = ca_private_key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.TraditionalOpenSSL,
        encryption_algorithm=serialization.NoEncryption()
    )

    # 证书链(根证书 + 中间证书)
    cert_chain_pem = root_cert_pem + intermediate_cert_pem
    print("证书链----------------------------------------------------")
    print(cert_chain_pem)
    print("cert_chain_pem",cert_chain_pem)
    print("Intermediate_CA", intermediate_certificate)

    return intermediate_certificate

3.数字签名生成

可以利用用户私钥生成数字签名,后使用服务端签发的证书对数字签名进行一个验证。

复制代码
def sign_data(data, private_key):
    # 加载私钥
    loaded_private_key = serialization.load_pem_private_key(
        private_key,
        password=None,
        backend=default_backend()
    )
    # 计算数据的哈希值
    digest = hashes.Hash(hashes.SHA256(), backend=default_backend())
    #data = b'some bytes data'


    if isinstance(data, str):
        digest.update(data.encode())

    #digest.update(data.encode())
    hashed_data = digest.finalize()

    # 使用私钥对哈希值进行签名
    signature = loaded_private_key.sign(
        hashed_data,
        padding.PKCS1v15(),
        hashes.SHA256()
    )

    return signature

4.数字证书验证数字签名的有效性

这里利用证书的公钥验证之前生成的数字签名的有效性。只是验证证书公钥有效性,未判断证书有无被吊销情况。

复制代码
import datetime
from cryptography import x509
from cryptography.x509.oid import NameOID
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, NoEncryption
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives.serialization import load_pem_private_key
from OpenSSL import crypto
import OpenSSL.crypto
import os
import base64
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization

#生成密钥函数
def generate_cakey(keysize):
    # 生成 CA 密钥对
    private_key = rsa.generate_private_key(
        public_exponent=65537,
        key_size=keysize,
        backend=default_backend()

    )
    ca_private_key = private_key.private_bytes(
        encoding=Encoding.PEM,
        format=PrivateFormat.PKCS8,
        encryption_algorithm=NoEncryption()
    )
    ca_public_key = private_key.public_key().public_bytes(
        encoding=Encoding.PEM,
        format=serialization.PublicFormat.SubjectPublicKeyInfo
    )
    print("生成密钥成功")
    return private_key,ca_private_key,ca_public_key

def load_key(key_path):
    with open(key_path, 'rb') as f:
        ca_key = f.read()

    return ca_key


def save_key(ca_private_key, ca_public_key):
    # 将私钥保存到文件
    with open('ca_private_key.pem', 'wb') as f:
        f.write(ca_private_key)

    # 将公钥保存到文件
    with open('ca_public_key.pem', 'wb') as f:
        f.write(ca_public_key)

    # 打印保存的密钥对文件名
    print("CA-key saved successfully -------------------------------")


def save_key2(ca_private_key, ca_public_key):
    # 将私钥保存到文件
    with open('usr_private_key.pem', 'wb') as f:
        f.write(ca_private_key)

    # 将公钥保存到文件
    with open('usr_public_key.pem', 'wb') as f:
        f.write(ca_public_key)

    # 打印保存的密钥对文件名
    print("USER-key saved successfully -------------------------------")


def generate_ca_certificate(name, province, country, user_private_key_pem, ca_private_key_pem, deadline):
    # 加载CA服务端密钥
    ca_private_key = serialization.load_pem_private_key(ca_private_key_pem, password=None, backend=default_backend())
    # 加载用户密钥
    user_private_key = serialization.load_pem_private_key(user_private_key_pem, password=None,
                                                          backend=default_backend())
    # 生成CA服务端证书
    root_subject = x509.Name([
        x509.NameAttribute(NameOID.COUNTRY_NAME, 'CN'),
        x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, 'Guangxi'),
        x509.NameAttribute(NameOID.LOCALITY_NAME, 'Guangxi'),
        x509.NameAttribute(NameOID.ORGANIZATION_NAME, 'CA'),
        x509.NameAttribute(NameOID.COMMON_NAME, 'CA'),
    ])
    root_issuer = root_subject  # 颁发者和主题一样

    before_now = datetime.datetime.utcnow()
    if deadline <= before_now:
        raise ValueError("Deadline must be in the future.")

    serial_number = x509.random_serial_number()

    # 根证书
    root_certificate = (
        x509.CertificateBuilder()
            .subject_name(root_subject)
            .issuer_name(root_issuer)
            .public_key(ca_private_key.public_key())
            .serial_number(serial_number)
            .not_valid_before(before_now)
            .not_valid_after(deadline)
            .add_extension(
            x509.BasicConstraints(ca=True, path_length=None), critical=True
        )
            .sign(ca_private_key, hashes.SHA256(), default_backend())
    )

    # 生成中间证书
    intermediate_subject = x509.Name([
        x509.NameAttribute(NameOID.COUNTRY_NAME, country),
        x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, province),
        x509.NameAttribute(NameOID.LOCALITY_NAME, province),
        x509.NameAttribute(NameOID.ORGANIZATION_NAME, name),
        x509.NameAttribute(NameOID.COMMON_NAME, name),
    ])
    intermediate_issuer = root_subject

    intermediate_certificate = (
        x509.CertificateBuilder()
            .subject_name(intermediate_subject)
            .issuer_name(intermediate_issuer)
            .public_key(user_private_key.public_key())
            .serial_number(x509.random_serial_number())
            .not_valid_before(before_now)
            .not_valid_after(deadline)
            .add_extension(
            x509.BasicConstraints(ca=True, path_length=None), critical=True
        )
            .sign(ca_private_key, hashes.SHA256(), default_backend())
    )

    # 转换为 PEM 格式
    root_cert_pem = root_certificate.public_bytes(serialization.Encoding.PEM)
    intermediate_cert_pem = intermediate_certificate.public_bytes(serialization.Encoding.PEM)

    # 私钥导出
    user_private_key_pem = user_private_key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.TraditionalOpenSSL,
        encryption_algorithm=serialization.NoEncryption()
    )
    ca_private_key_pem = ca_private_key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.TraditionalOpenSSL,
        encryption_algorithm=serialization.NoEncryption()
    )

    # 证书链(根证书 + 中间证书)
    cert_chain_pem = root_cert_pem + intermediate_cert_pem
    print("证书链----------------------------------------------------")
    print(cert_chain_pem)
    print("cert_chain_pem", cert_chain_pem)
    print("Intermediate_CA", intermediate_certificate)

    return intermediate_certificate
#保存证书
def save_certificate_to_file(certificate, filename):
    with open(filename, "wb") as file:
        file.write(certificate)

def sign_data(data, private_key):
    # 加载私钥
    loaded_private_key = serialization.load_pem_private_key(
        private_key,
        password=None,
        backend=default_backend()
    )
    # 计算数据的哈希值
    digest = hashes.Hash(hashes.SHA256(), backend=default_backend())
    #data = b'some bytes data'


    if isinstance(data, str):
        digest.update(data.encode())

    #digest.update(data.encode())
    hashed_data = digest.finalize()

    # 使用私钥对哈希值进行签名
    signature = loaded_private_key.sign(
        hashed_data,
        padding.PKCS1v15(),
        hashes.SHA256()
    )

    return signature

def verify_signature(data, signature, certificate):
    # 加载证书
    loaded_certificate = x509.load_pem_x509_certificate(
        certificate,
        default_backend()
    )
    # 提取公钥
    public_key = loaded_certificate.public_key()

    # 计算数据的哈希值
    digest = hashes.Hash(hashes.SHA256(), backend=default_backend())
    hashed_data = digest.finalize()

    try:
        # 使用公钥验证签名
        public_key.verify(
            signature,
            hashed_data,
            padding.PKCS1v15(),
            hashes.SHA256()
        )
        print("签名验证成功")
        return True
    except Exception:
        print("签名验证失败")
        return False

if __name__ == "__main__":
    keysize = 2048  # 密钥长度
    time0 = "2026-1-1"
    time1 = "00:00:00"
    date_string = time0 + " " + time1
    format_string = '%Y-%m-%d %H:%M:%S'  # 把时间转换为标准时间
    datetime_obj = datetime.datetime.strptime(date_string, format_string)
    print('datetime_obj', datetime_obj)
    # 生成服务端公私钥
    private_key, ca_private_key, ca_public_key = generate_cakey(keysize)
    # 生成用户端公私钥
    private_key2, usr_private_key2, usr_public_key2 = generate_cakey(keysize)
    # 保存密钥为pem格式
    save_key(ca_private_key,ca_public_key)
    save_key2(usr_private_key2,usr_public_key2)

    ca_private_key_path = 'ca_private_key.pem'  # 密钥文件的路径
    ca_public_key_path = 'ca_public_key.pem'
    #加载密钥文件
    ca_private_key = load_key(ca_private_key_path)
    ca_public_key = load_key(ca_public_key_path)
    #先保存再打开看似有点奇怪,利于后面写系统

    usr_private_key_path = 'usr_private_key.pem'
    usr_public_key_path = 'usr_public_key.pem'
    user_private_key = load_key(usr_private_key_path)
    user_public_key = load_key(usr_public_key_path)
    # 打印密钥内容
    print("ca_private_key", ca_private_key)
    print("ca_public_key", ca_public_key)
    print("user_private_key", user_private_key)
    print("user_public_key", user_public_key)
    # 生成 CA 证书
    name = 'xiaoxi'
    province = "Guangxi"
    country = "CN"
    ca_certificate = generate_ca_certificate(name, province, country, user_private_key,ca_private_key, datetime_obj)
    print("ca_certificate", ca_certificate)

    ca_certificate_bytes = ca_certificate.public_bytes(encoding=serialization.Encoding.PEM)
    script_dir = os.path.dirname(os.path.abspath(__file__))
    # 构建保存证书的文件夹路径
    ca_folder = os.path.join(script_dir, 'my_ca')
    os.makedirs(ca_folder, exist_ok=True)
    ca_path = os.path.join(ca_folder, "ca_certificate.crt")
    save_certificate_to_file(ca_certificate_bytes, ca_path)
    #数字签名data文件
    data = b'hello'
    signature = sign_data(data, user_private_key)
    # 使用签发的证书对数字签名进行验证
    is_valid = verify_signature(data, signature, ca_certificate_bytes)

算法运行截图

生成的证书

完整算法代码

复制代码
import datetime
from cryptography import x509
from cryptography.x509.oid import NameOID
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, NoEncryption
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives.serialization import load_pem_private_key
from OpenSSL import crypto
import OpenSSL.crypto
import os
import base64
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization

#生成密钥函数
def generate_cakey(keysize):
    # 生成 CA 密钥对
    private_key = rsa.generate_private_key(
        public_exponent=65537,
        key_size=keysize,
        backend=default_backend()

    )
    ca_private_key = private_key.private_bytes(
        encoding=Encoding.PEM,
        format=PrivateFormat.PKCS8,
        encryption_algorithm=NoEncryption()
    )
    ca_public_key = private_key.public_key().public_bytes(
        encoding=Encoding.PEM,
        format=serialization.PublicFormat.SubjectPublicKeyInfo
    )
    print("生成密钥成功")
    return private_key,ca_private_key,ca_public_key

def load_key(key_path):
    with open(key_path, 'rb') as f:
        ca_key = f.read()

    return ca_key


def save_key(ca_private_key, ca_public_key):
    # 将私钥保存到文件
    with open('ca_private_key.pem', 'wb') as f:
        f.write(ca_private_key)

    # 将公钥保存到文件
    with open('ca_public_key.pem', 'wb') as f:
        f.write(ca_public_key)

    # 打印保存的密钥对文件名
    print("CA-key saved successfully -------------------------------")


def save_key2(ca_private_key, ca_public_key):
    # 将私钥保存到文件
    with open('usr_private_key.pem', 'wb') as f:
        f.write(ca_private_key)

    # 将公钥保存到文件
    with open('usr_public_key.pem', 'wb') as f:
        f.write(ca_public_key)

    # 打印保存的密钥对文件名
    print("USER-key saved successfully -------------------------------")


def generate_ca_certificate(name, province, country, user_private_key_pem, ca_private_key_pem, deadline):
    # 加载CA服务端密钥
    ca_private_key = serialization.load_pem_private_key(ca_private_key_pem, password=None, backend=default_backend())
    # 加载用户密钥
    user_private_key = serialization.load_pem_private_key(user_private_key_pem, password=None,
                                                          backend=default_backend())
    # 生成CA服务端证书
    root_subject = x509.Name([
        x509.NameAttribute(NameOID.COUNTRY_NAME, 'CN'),
        x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, 'Guangxi'),
        x509.NameAttribute(NameOID.LOCALITY_NAME, 'Guangxi'),
        x509.NameAttribute(NameOID.ORGANIZATION_NAME, 'CA'),
        x509.NameAttribute(NameOID.COMMON_NAME, 'CA'),
    ])
    root_issuer = root_subject  # 颁发者和主题一样

    before_now = datetime.datetime.utcnow()
    if deadline <= before_now:
        raise ValueError("Deadline must be in the future.")

    serial_number = x509.random_serial_number()

    # 根证书
    root_certificate = (
        x509.CertificateBuilder()
            .subject_name(root_subject)
            .issuer_name(root_issuer)
            .public_key(ca_private_key.public_key())
            .serial_number(serial_number)
            .not_valid_before(before_now)
            .not_valid_after(deadline)
            .add_extension(
            x509.BasicConstraints(ca=True, path_length=None), critical=True
        )
            .sign(ca_private_key, hashes.SHA256(), default_backend())
    )

    # 生成中间证书
    intermediate_subject = x509.Name([
        x509.NameAttribute(NameOID.COUNTRY_NAME, country),
        x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, province),
        x509.NameAttribute(NameOID.LOCALITY_NAME, province),
        x509.NameAttribute(NameOID.ORGANIZATION_NAME, name),
        x509.NameAttribute(NameOID.COMMON_NAME, name),
    ])
    intermediate_issuer = root_subject

    intermediate_certificate = (
        x509.CertificateBuilder()
            .subject_name(intermediate_subject)
            .issuer_name(intermediate_issuer)
            .public_key(user_private_key.public_key())
            .serial_number(x509.random_serial_number())
            .not_valid_before(before_now)
            .not_valid_after(deadline)
            .add_extension(
            x509.BasicConstraints(ca=True, path_length=None), critical=True
        )
            .sign(ca_private_key, hashes.SHA256(), default_backend())
    )

    # 转换为 PEM 格式
    root_cert_pem = root_certificate.public_bytes(serialization.Encoding.PEM)
    intermediate_cert_pem = intermediate_certificate.public_bytes(serialization.Encoding.PEM)

    # 私钥导出
    user_private_key_pem = user_private_key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.TraditionalOpenSSL,
        encryption_algorithm=serialization.NoEncryption()
    )
    ca_private_key_pem = ca_private_key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.TraditionalOpenSSL,
        encryption_algorithm=serialization.NoEncryption()
    )

    # 证书链(根证书 + 中间证书)
    cert_chain_pem = root_cert_pem + intermediate_cert_pem
    print("证书链----------------------------------------------------")
    print(cert_chain_pem)
    print("cert_chain_pem", cert_chain_pem)
    print("Intermediate_CA", intermediate_certificate)

    return intermediate_certificate
#保存证书
def save_certificate_to_file(certificate, filename):
    with open(filename, "wb") as file:
        file.write(certificate)

def sign_data(data, private_key):
    # 加载私钥
    loaded_private_key = serialization.load_pem_private_key(
        private_key,
        password=None,
        backend=default_backend()
    )
    # 计算数据的哈希值
    digest = hashes.Hash(hashes.SHA256(), backend=default_backend())
    #data = b'some bytes data'


    if isinstance(data, str):
        digest.update(data.encode())

    #digest.update(data.encode())
    hashed_data = digest.finalize()

    # 使用私钥对哈希值进行签名
    signature = loaded_private_key.sign(
        hashed_data,
        padding.PKCS1v15(),
        hashes.SHA256()
    )

    return signature

def verify_signature(data, signature, certificate):
    # 加载证书
    loaded_certificate = x509.load_pem_x509_certificate(
        certificate,
        default_backend()
    )
    # 提取公钥
    public_key = loaded_certificate.public_key()

    # 计算数据的哈希值
    digest = hashes.Hash(hashes.SHA256(), backend=default_backend())
    hashed_data = digest.finalize()

    try:
        # 使用公钥验证签名
        public_key.verify(
            signature,
            hashed_data,
            padding.PKCS1v15(),
            hashes.SHA256()
        )
        print("签名验证成功")
        return True
    except Exception:
        print("签名验证失败")
        return False

if __name__ == "__main__":
    keysize = 2048  # 密钥长度
    time0 = "2026-1-1"
    time1 = "00:00:00"
    date_string = time0 + " " + time1
    format_string = '%Y-%m-%d %H:%M:%S'  # 把时间转换为标准时间
    datetime_obj = datetime.datetime.strptime(date_string, format_string)
    print('datetime_obj', datetime_obj)
    # 生成服务端公私钥
    private_key, ca_private_key, ca_public_key = generate_cakey(keysize)
    # 生成用户端公私钥
    private_key2, usr_private_key2, usr_public_key2 = generate_cakey(keysize)
    # 保存密钥为pem格式
    save_key(ca_private_key,ca_public_key)
    save_key2(usr_private_key2,usr_public_key2)

    ca_private_key_path = 'ca_private_key.pem'  # 密钥文件的路径
    ca_public_key_path = 'ca_public_key.pem'
    #加载密钥文件
    ca_private_key = load_key(ca_private_key_path)
    ca_public_key = load_key(ca_public_key_path)
    #先保存再打开看似有点奇怪,利于后面写系统

    usr_private_key_path = 'usr_private_key.pem'
    usr_public_key_path = 'usr_public_key.pem'
    user_private_key = load_key(usr_private_key_path)
    user_public_key = load_key(usr_public_key_path)
    # 打印密钥内容
    print("ca_private_key", ca_private_key)
    print("ca_public_key", ca_public_key)
    print("user_private_key", user_private_key)
    print("user_public_key", user_public_key)
    # 生成 CA 证书
    name = 'xiaoxi'
    province = "Guangxi"
    country = "CN"
    ca_certificate = generate_ca_certificate(name, province, country, user_private_key,ca_private_key, datetime_obj)
    print("ca_certificate", ca_certificate)

    ca_certificate_bytes = ca_certificate.public_bytes(encoding=serialization.Encoding.PEM)
    script_dir = os.path.dirname(os.path.abspath(__file__))
    # 构建保存证书的文件夹路径
    ca_folder = os.path.join(script_dir, 'server_ca')
    os.makedirs(ca_folder, exist_ok=True)
    ca_path = os.path.join(ca_folder, "ca_certificate.crt")
    save_certificate_to_file(ca_certificate_bytes, ca_path)
    #数字签名data文件
    data = b'hello'
    signature = sign_data(data, user_private_key)
    # 使用签发的证书对数字签名进行验证
    is_valid = verify_signature(data, signature, ca_certificate_bytes)

证书的吊销

证书的吊销参考这篇文章

证书吊销列表(CRL) - 程翔北 - 博客园

需要生成一个证书吊销列表CRL然后把吊销的证书序列号添加进去。

完整算法代码

复制代码
import os
from cryptography import x509
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.backends import default_backend
from datetime import datetime, timedelta


def add_certificate_to_crl():
    crl_file_path = "H:/CA_demo/crl_list.crl"
    ca_private_key_path = "H:/CA_demo/ca_private_key.pem"
    # 要吊销的证书序列号
    target_serial_number = 1234 #会转化为16进制
    try:
        if not os.path.exists(crl_file_path):
            # 构建 CRL 发布者/颁发者名称
            issuer_name = x509.Name([
                x509.NameAttribute(NameOID.COUNTRY_NAME, "CN"),
                x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "Guangxi"),
                x509.NameAttribute(NameOID.LOCALITY_NAME, "Guangxi"),
                x509.NameAttribute(NameOID.ORGANIZATION_NAME, "CA"),
            ])
            # 构建 CRL 列表生成器
            builder = x509.CertificateRevocationListBuilder().issuer_name(x509.Name(issuer_name))
            # 设置 CRL 的有效期
            this_update = datetime.utcnow()
            next_update = this_update + timedelta(days=1)
            builder = builder.last_update(this_update).next_update(next_update)
        else:
            with open(crl_file_path, "rb") as crl_file:
                crl_data = crl_file.read()
            # 解析现有的 CRL 数据
            crl = x509.load_pem_x509_crl(crl_data, default_backend())
            builder = x509.CertificateRevocationListBuilder().issuer_name(crl.issuer)
            # 将现有的吊销证书添加到新的 CRL 中
            for revoked_certificate in crl:
                builder = builder.add_revoked_certificate(revoked_certificate)
            # 更新最后更新时间
            this_update = datetime.utcnow()
            # 设置下一次更新时间
            next_update = this_update + timedelta(days=1)
            builder = builder.last_update(this_update).next_update(next_update)
        # 创建新的吊销证书
        now = datetime.utcnow()
        revoked_certificate = x509.RevokedCertificateBuilder().serial_number(target_serial_number).revocation_date(now).build()
        builder = builder.add_revoked_certificate(revoked_certificate)
        # 使用 CA 私钥对 CRL 进行签名
        with open(ca_private_key_path, 'rb') as key_file:
            private_key = serialization.load_pem_private_key(
                key_file.read(),
                password=None,
                backend=default_backend()
            )
        crl = builder.sign(
            private_key=private_key,
            algorithm=hashes.SHA256(),
            backend=default_backend()
        )
        # 将更新后的 CRL 列表保存到文件
        with open(crl_file_path, "wb") as crl_file:
            crl_file.write(crl.public_bytes(serialization.Encoding.PEM))
        print(f"证书序列号 {target_serial_number} 已添加到 CRL 中。")
    except Exception as e:
        print(f"发生错误: {e}")


if __name__ == "__main__":
    add_certificate_to_crl()

算法运行截图

CRL文件里面有新的吊销的序列号和日期,此处为了简化演示才输入1234,正常情况是要需要吊销证书的真实序列号。

系统测试

客户端界面

服务端界面

相关推荐
XINVRY-FPGA2 分钟前
Xilinx XCAU10P-2FFVB676I 赛灵思 Artix UltraScale+ FPGA
嵌入式硬件·安全·阿里云·ai·fpga开发·云计算·fpga
我不是立达刘宁宇6 分钟前
Python Paramiko上传文件到win ser2022服务器和反向
运维·服务器
一匹电信狗6 分钟前
【Linux我做主】探秘进程与fork
linux·运维·服务器·c++·ubuntu·小程序·unix
ZZZKKKRTSAE12 分钟前
快速上手Linux火墙管理
linux·运维·服务器·防火墙
平生不喜凡桃李1 小时前
Linux 文件(3)
linux·运维·服务器
TDengine (老段)1 小时前
TDengine 运维—容量规划
大数据·运维·数据库·时序数据库·tdengine·涛思数据·iotdb
todoitbo2 小时前
开源一个记账软件,支持docker一键部署
运维·docker·容器·开源·springboot·记账软件·容器部署
安顾里2 小时前
什么是endpoints?
运维·容器·kubernetes
风屿.2 小时前
IDEA推送到gitlab,jenkins识别,然后自动发布到需要的主机
运维·gitlab·jenkins
云祺vinchin3 小时前
云祺容灾备份系统公有云备份与恢复实操-华为云
运维·服务器