m0_74734457 2024-04-01 17:40 采纳率: 40%
浏览 16

使用python模块cryptography.x509创建自签名证书和为server签名,验证签名时报错: `Certificate is missing required extension`

使用python模块cryptography.x509创建自签名证书和为server签名,验证签名时报错:
Certificate is missing required extension
应该添加什么必要的扩展呢?

生成证书代码:

# 使用自签名签发服务器签名
def generate_sign_sret():

    with open("csr.pem", "rb") as f:
        pem_req_data = f.read()
    server_csr = x509.load_pem_x509_csr(pem_req_data)
    with open("cert.pem", "rb") as f:
        ca_pem_req_data = f.read()
    ca_cert = x509.load_pem_x509_certificate(ca_pem_req_data)
    # 签发服务器证书
    server_cert = (
        x509.CertificateBuilder()
        # 服务器请求信息
        .subject_name(server_csr.subject)
        # 自签名证书
        .issuer_name(ca_cert.subject)
        .public_key(server_csr.public_key())
        .serial_number(x509.random_serial_number())
        .not_valid_before(datetime.now() - timedelta(days=1))
        # 有效期一年
        .not_valid_after(datetime.now() + timedelta(days=365))
        .add_extension(
            # x509.BasicConstraints(ca=False, path_length=None),
            x509.SubjectAlternativeName([x509.DNSName("cryptography.io")]),
            # critical=True,
            critical=False,
        )
        .add_extension(
            x509.BasicConstraints(ca=False, path_length=None),
            critical=True,
        )
        .add_extension(
            x509.KeyUsage(True, True, True, True, True, False, True, True, True),
            critical=True,
        )
        # 使用CA的私钥签发
        .sign(key, SHA256(), default_backend())
    )
    server_cert_bytes = server_cert.public_bytes(encoding=serialization.Encoding.PEM)
    with open("server_cert.pem", "wb") as f:
        f.write(server_cert_bytes)

验证函数:

# 验签
def verifyCert():
    with open("cert.pem", "rb") as f:
        ca_pem_req_data = f.read()
    ca_cert = x509.load_pem_x509_certificate(ca_pem_req_data)

    with open("server_cert.pem", "rb") as f:
        server_pem_req_data = f.read()
    server_cert = x509.load_pem_x509_certificate(server_pem_req_data)

    with open(certifi.where(), "rb") as pems:
        store = Store(x509.load_pem_x509_certificates(pems.read()))
    # 创建一个受信任的store
    trust_builder = PolicyBuilder().store(store)
    verifier = trust_builder.build_server_verifier(x509.DNSName("cryptography.io"))
    try:
        verifier.verify(server_cert, [server_cert, ca_cert])
        print("Server certificate is valid.")
    except Exception as e:
        print("Server certificate validation failed:", e)
  • 写回答

2条回答 默认 最新

  • 码农阿豪@新空间代码工作室 Java领域优质创作者 2024-04-01 17:40
    关注
    让阿豪来帮你解答,本回答参考chatgpt3.5编写提供,如果还有疑问可以评论或留言
    根据错误提示,应该添加扩展"KeyUsage",这个扩展定义证书如何使用密钥,包括数字签名和加密等。 添加"KeyUsage"扩展的代码块如下:
    .add_extension(
        x509.KeyUsage(
            digital_signature=True,
            content_commitment=True,
            key_encipherment=True,
            data_encipherment=True,
            key_agreement=False,
            key_cert_sign=False,
            crl_sign=False,
            encipher_only=False,
            decipher_only=False,
        ),
        critical=True,
    )
    

    完整生成证书代码:

    # 使用自签名签发服务器签名
    def generate_sign_sret():
        with open("csr.pem", "rb") as f:
            pem_req_data = f.read()
        server_csr = x509.load_pem_x509_csr(pem_req_data)
        with open("cert.pem", "rb") as f:
            ca_pem_req_data = f.read()
        ca_cert = x509.load_pem_x509_certificate(ca_pem_req_data)
        
        # 签发服务器证书
        server_cert = (
            x509.CertificateBuilder()
            # 服务器请求信息
            .subject_name(server_csr.subject)
            # 自签名证书
            .issuer_name(ca_cert.subject)
            .public_key(server_csr.public_key())
            .serial_number(x509.random_serial_number())
            .not_valid_before(datetime.utcnow())
            # 有效期一年
            .not_valid_after(datetime.utcnow() + timedelta(days=365))
            .add_extension(
                # 扩展1:添加SubjectAlternativeName
                x509.SubjectAlternativeName([x509.DNSName("cryptography.io")]),
                critical=False,
            )
            .add_extension(
                # 扩展2:添加BasicConstraints
                x509.BasicConstraints(ca=False, path_length=None),
                critical=True,
            )
            .add_extension(
                # 扩展3:添加KeyUsage
                x509.KeyUsage(
                    digital_signature=True,
                    content_commitment=True,
                    key_encipherment=True,
                    data_encipherment=True,
                    key_agreement=False,
                    key_cert_sign=False,
                    crl_sign=False,
                    encipher_only=False,
                    decipher_only=False,
                ),
                critical=True,
            )
            .sign(key, SHA256(), default_backend())
        )
        server_cert_bytes = server_cert.public_bytes(encoding=serialization.Encoding.PEM)
        with open("server_cert.pem", "wb") as f:
            f.write(server_cert_bytes)
    

    完整验证函数代码:

    # 验签
    def verify_Cert():
        with open("cert.pem", "rb") as f:
            ca_pem_req_data = f.read()
        ca_cert = x509.load_pem_x509_certificate(ca_pem_req_data)
        with open("server_cert.pem", "rb") as f:
            server_pem_req_data = f.read()
        server_cert = x509.load_pem_x509_certificate(server_pem_req_data)
        with open(certifi.where(), "rb") as pems:
            store = Store(x509.load_pem_x509_certificates(pems.read()))
        # 创建一个受信任的store
        trust_builder = PolicyBuilder().store(store)
        verifier = trust_builder.build_server_cert_verifier(x509.DNSName("cryptography.io"))
        try:
            verifier.verify(server_cert, [server_cert, ca_cert])
            print("Server certificate is valid.")
        except Exception as e:
            print("Server certificate validation failed:", e)
    
    评论

报告相同问题?

问题事件

  • 创建了问题 4月1日

悬赏问题

  • ¥15 Qt6.8.0加载网页MSVC2022
  • ¥15 360浏览器m2的这个值
  • ¥15 国内有哪些厂商做automlops的?
  • ¥15 skynet pb mysql
  • ¥15 笔记本外接显示器分辨率太低各种方法都用过了调不高
  • ¥15 Redstone R0697-F00 D2020 交换机 OS
  • ¥50 H5+js 动态数字画廊怎么做?
  • ¥20 外向内全景图像拼接相关项目和论文咨询
  • ¥20 请写个前端案例学习使用
  • ¥15 FFmpeg中G.711转AAC报错:[aac @ 0000014f803ab640] Input contains (near) NaN/+-Inf