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

时间:2019-01-23 19:56:55

标签: python-3.x cryptography certificate mosquitto paho

我正在尝试以编程方式创建供mosquitto客户端使用的客户端证书。使用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

这有效。

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

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变体和自动变体。他们看上去和我差不多。但是,该子项无效:

$ 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 个答案:

答案 0 :(得分:0)

另一个来源指出的问题是,我使用与生成证书相同的密钥对新证书进行签名。就像颁发名称要与颁发证书的名称一样,签名密钥应该是同一颁发证书的私钥。用类似如下的内容替换签名子句:

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()
)