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

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:30
    关注
    让阿豪来帮你解答,本回答参考chatgpt3.5编写提供,如果还有疑问可以评论或留言
    根据错误提示,应该添加Subject Key Identifier扩展,可以通过以下方式添加: .add_extension( x509.SubjectKeyIdentifier.from_public_key(server_cert.public_key()), critical=False, ) 修改后的代码如下:

    使用自签名签发服务器签名

    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.SubjectAlternativeName([x509.DNSName("cryptography.io")]), critical=False, ) .add_extension( x509.BasicConstraints(ca=False, path_length=None), critical=True, ) .add_extension( x509.KeyUsage( digital_signature=True, content_commitment=False, key_encipherment=True, data_encipherment=True, key_agreement=True, key_cert_sign=False, crl_sign=True, encipher_only=True, decipher_only=True, ), critical=True, ) .add_extension( x509.SubjectKeyIdentifier.from_public_key(server_cert.public_key()), critical=False, ) # 使用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 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_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 Opencv配置出错
  • ¥15 模电中二极管,三极管和电容的应用
  • ¥15 关于模型导入UNITY的.FBX: Check external application preferences.警告。
  • ¥15 气象网格数据与卫星轨道数据如何匹配
  • ¥100 java ee ssm项目 悬赏,感兴趣直接联系我
  • ¥15 微软账户问题不小心注销了好像
  • ¥15 x264库中预测模式字IPM、运动向量差MVD、量化后的DCT系数的位置
  • ¥15 curl 命令调用正常,程序调用报 java.net.ConnectException: connection refused
  • ¥20 关于web前端如何播放二次加密m3u8视频的问题
  • ¥15 使用百度地图api 位置函数报错?