代码之家  ›  专栏  ›  技术社区  ›  Travis Griggs

尝试使用python3.cryptography自动生成证书;运气不佳

  •  0
  • Travis Griggs  · 技术社区  · 5 年前

    我正在尝试以编程方式创建供大多数客户使用的客户机证书。使用XCA,我可以创建一个自签名的CA、一个中介,然后从中介创建一个证书。我已经用“Require Certificate true”选项配置了mosquitto。使用XCA导出的密钥,我可以使用Paho客户机进行测试:

     mosquitto_sub -h ubuntu -p 8765 -t /1/2/3 --cafile ~/CA2/Chain.crt -d --cert ./test1.crt --key ./test1.pem
    

    这是可行的。

    现在,我尝试使用python3脚本自动生成密钥 cryptography 模块。

    from cryptography.hazmat.backends import default_backend
    from cryptography.hazmat.primitives import serialization
    from cryptography.hazmat.primitives.asymmetric import rsa
    from cryptography import x509
    from cryptography.hazmat.primitives import hashes
    from cryptography.x509.oid import NameOID
    from pathlib import Path
    from datetime import datetime, timezone, timedelta
    import uuid
    
    privateKey = rsa.generate_private_key(
        public_exponent=65537,
        key_size=4096,
        backend=default_backend())
    with Path('test2.pem').open('wb') as stream:
        stream.write(privateKey.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.TraditionalOpenSSL,
            encryption_algorithm=serialization.NoEncryption()))
    
    builder = x509.CertificateBuilder()
    builder = builder.subject_name(x509.Name([
        x509.NameAttribute(NameOID.COMMON_NAME, uuid.uuid4().hex),
    ]))
    builder = builder.issuer_name(x509.Name([
        x509.NameAttribute(NameOID.COMMON_NAME, u'ubuntu'),
    ]))
    builder = builder.not_valid_before(datetime.now(timezone.utc) - timedelta(days=1))
    builder = builder.not_valid_after(datetime.now(timezone.utc) + timedelta(days=365*50))
    builder = builder.serial_number(x509.random_serial_number())
    builder = builder.public_key(privateKey.public_key())
    builder = builder.add_extension(
        x509.BasicConstraints(ca=False, path_length=None), critical=True,
    )
    builder = builder.add_extension(
        x509.SubjectKeyIdentifier.from_public_key(privateKey.public_key()), critical=False,
    )
    builder = builder.add_extension(
        x509.KeyUsage(digital_signature=True,
            content_commitment=False,
            key_encipherment=True,
            data_encipherment=True,
            key_agreement=False,
            key_cert_sign=False,
            crl_sign=False,
            encipher_only=False,
            decipher_only=False), critical=False,
    )
    certificate = builder.sign(
        private_key=privateKey, algorithm=hashes.SHA256(),
        backend=default_backend()
    )
    
    print(certificate)
    with Path('test2.crt').open('wb') as stream:
        stream.write(certificate.public_bytes(encoding=serialization.Encoding.PEM))
    

    我已经用过 openssl x509 -in certFile.crt -text -noout 比较XCA变量和我的自动变量。他们看起来和我几乎一模一样。但是,SUB不工作:

    $ mosquitto_sub -h ubuntu -p 8765 -t /1/2/3 --cafile ~/CA2/Chain.crt -d --cert ./cert.crt --key ./key.pem 
    Client mosqsub|34613-ubuntu sending CONNECT
    Error: A TLS error occurred.
    
    1 回复  |  直到 5 年前
        1
  •  0
  •   Travis Griggs    5 年前

    另一个源中指出的问题是,我正在用生成证书时使用的密钥对新证书进行签名。与颁发证书的名称相同,签名密钥应该是同一颁发证书的私钥。将签名子句替换为如下内容:

    parentKey = serialization.load_pem_private_key(
        Path('path/to/intermediate_key.pem').read_bytes(),
        password=None,
        backend=default_backend())
    certificate = builder.sign(
        private_key=parentKey,
        algorithm=hashes.SHA256(),
        backend=default_backend()
    )