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

news2025/1/4 15:21:42

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,正常情况是要需要吊销证书的真实序列号。

系统测试 

客户端界面

服务端界面

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2269771.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

phpstudy2018问题(技巧)总结

目录 安装介绍注意操作 问题phpstudy待续、更新中...... 安装 软件下载&#xff08;新人推荐2018 版本phpstudy &#xff09; 官网下载 https://www.xp.cn/download.html 介绍 系统服务------开机自启 非服务模式------开机不自启 搭建好环境, 此时服务器与客户端同时存在 …

USB2.0之描述符(Descriptors)

文章目录 描述符(Descriptors)设备描述符(Device Descriptors)配置描述符(Configuration Descriptors)接口描述符(Interface Descriptors)端点描述符(Endpoint Descriptors)字符串描述符(String Descriptors) 参考资料 描述符(Descriptors) 描述符是设备本身各项信息的集合&…

从授权校验看SpringBoot自动装配

背景 最近需要实现一个对于系统的授权检测功能&#xff0c;即当SpringBoot应用被启动时&#xff0c;需要当前设备是否具有有效的的授权许可信息&#xff0c;若无则直接退出应用。具体的实现方案请继续看下文。 环境 Ruoyi-Vue SpringBoot3 RuoYi-Vue: &#x1f389; 基于Spr…

jmeter分布式启动

https://www.cnblogs.com/qtclm/p/11082081.html 1、代理机&#xff1a;输入“ipconfig”&#xff0c;找到IP地址&#xff0c;在Jmeter/bin/jmeter.properties设置remote host 启动jmeter server 1、控制机&#xff1a;输入“ipconfig”&#xff0c;找到IP地址&#xff0c;在J…

SpringCloud源码-Ribbon

一、Spring定制化RestTemplate&#xff0c;预留出RestTemplate定制化扩展点 org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration 二、Ribbon定义RestTemplate Ribbon扩展点功能 org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguratio…

目标检测,语义分割标注工具--labelimg labelme

1 labelimg labelimg可以用来标注目标检测的数据集&#xff0c; 提供多种格式的输出&#xff0c; 如Pascal Voc, YOLO等。 1.1 安装 pip install labelimg1.2 使用 命令行直接输入labelimg即可打开软件主界面进行操作。 使用非常简单&#xff0c; 不做过细的介绍&#xff0…

pd虚拟机 [po] Parallels Desktop 20 激活 for Mac [jie] 安装教程【支持M芯片】

文章目录 效果图一、下载软件二、安装运行⚠️注意事项&#xff1a;1、前往 系统设置–> 隐私与安全性 –> 完整磁盘访问权限&#xff0c;中允许终端&#xff1a;2、安装运行【ParallelsDesktop-20.1.2-55742.dmg】&#xff0c;运行【安装.app】3、将【Patch】文件夹拖到…

windows11安装软件时选择文件路径只有桌面及子文件夹怎么解决方法

现象&#xff1a;当桌面文件夹、文件总数超过一定数量时(具体个数不详&#xff0c;个人猜测可能跟系统架构或内存有关)点击应用程序中“浏览”按钮时&#xff0c;只能看到桌面文件夹&#xff0c;其他盘符看不到。一个巨硬愚蠢的bug。定期清理下桌面吧&#xff0c;习惯下载到桌面…

SpringCloud源码-openFeign

LoadBalancer默认只有nacos服务发现器 openFeign与springcloud loadbalancer的结合点 openFeign通过spring cloud loadbalancer进行负载均衡&#xff0c;spring cloud loadbalancer通过discovery client获取nacos的机器列表&#xff0c;然后底层进行负载均衡。

开源架构中的数据库选择优化版

上一篇文章推荐&#xff1a; 开源架构学习指南&#xff1a;文档与资源的智慧锦囊&#xff08;New&#xff09; 我管理的社区推荐&#xff1a;【青云交社区】和【架构师社区】 推荐技术圈福利社群&#xff1a;点击快速加入 开源架构中的数据库选择优化版 一、引言二、关系型开源…

Listwise 排序之 LambdaRank:最大化 NDCG 的秘诀

Listwise系列相关文章&#xff08;置顶&#xff09; 1.Listwise 模型时间线梳理 2.Listwise 排序之 LambdaRank&#xff1a;最大化 NDCG 的秘诀 引言 LambdaRank 是一种用于排序学习&#xff08;Learning to Rank, LTR&#xff09;的模型&#xff0c;特别适用于推荐系统和信息…

汉化SecureCRT9.1

我个人觉得&#xff0c;SecureCRT是最好用的ssh远程工具软件&#xff0c;但是这个软件没有中文版本&#xff0c;我这种英文水平糟糕的人用起来&#xff0c;略有不便&#xff0c;因为一直没有在网上找到合适的汉化版本&#xff0c;于是有自己做一个汉化版本的计划。 前几日&…

我在广州学 Mysql 系列——插入、更新与删除数据详解以及实例

ℹ️大家好&#xff0c;我是练小杰&#xff0c;今天是2024年12月30号&#xff0c;明天就是2024最后一天了&#xff01;&#xff01; 本文将讲述MYSQL数据库的插入&#xff0c;更新以及删除数据~~ 复习&#xff1a;&#x1f449;【有关Mysql数据库的单表&#xff0c;多表查询的练…

HarmonyOS Next ArkUI ListListItem笔记

学习目标&#xff1a; List和ListItem的使用 学习内容&#xff1a; import { NewsInfo, newsInfoList } from ../viewmodel/NewsInfoclass DividerTmp {strokeWidth: Length 1startMargin: Length 60endMargin: Length 10color: ResourceColor #ffe9f0f0constructor(str…

机器人C++开源库The Robotics Library (RL)使用手册(四)

建立自己的机器人3D模型和运动学模型 这里以国产机器人天机TR8为例,使用最普遍的DH运动学模型,结合RL所需的描述文件,进行生成。 最终,需要的有两个文件,一个是.wrl三维模型描述文件;一个是.xml运动学模型描述文件。 1、通过STEP/STP三维文件生成wrl三维文件 机器人的…

游戏引擎学习第70天

这一节没讲什么主要是关于接下来要干的任务 开发过程概览 我们正在进行最后的总结&#xff0c;并计划接下来的步骤。目前的目标是创建一个包含所有必要组件的游戏引擎原型版本&#xff0c;目的是让这些部分能够协同工作并展现预期效果。通过这一过程&#xff0c;可以实验和探…

Android笔试面试题AI答之Android基础(8)

Android入门请看《Android应用开发项目式教程》&#xff0c;视频、源码、答疑&#xff0c;手把手教 文章目录 1.Android新建工程需要注意的地方有哪些&#xff1f;**1. 选择合适的项目模板****2. 配置项目基本信息****3. 选择最低 SDK 版本****4. 配置构建工具****5. 选择编程…

传统听写与大模型听写比对

在快节奏的现代生活中&#xff0c;听写技能仍然是学习语言和提升认知能力的重要环节。然而&#xff0c;传统的听写练习往往枯燥乏味&#xff0c;且效率不高。现在&#xff0c;随着人工智能技术的发展&#xff0c;大模型听写工具的问世&#xff0c;为传统听写带来了革命性的变革…

赛博周刊·2024年度工具精选(画板二维码类)

一、画板类 1、Excalidraw 一款好用的手绘工具&#xff0c;无需注册&#xff0c;支持多人协作。GitHub项目地址&#xff1a;https://github.com/excalidraw/excalidraw。 2、 Floating Whiteboard 一个在线的网页白板工具。 3、BoardOS&#xff1a;在线实时白板协作系统 一…

论文研读:Text2Video-Zero 无需微调,仅改动<文生图模型>推理函数实现文生视频(Arxiv 2023-03-23)

论文名&#xff1a;Text2Video-Zero: Text-to-Image Diffusion Models are Zero-Shot Video Generators 1. 摘要 1.1 方法总结 通过潜空间插值, 实现动作连续帧。 以第一帧为锚定&#xff0c;替换原模型的self-attention&#xff0c;改为cross-attention 实现 保证图片整体场…