尝试使用 python3.cryptography 自动生成证书;没有运气
Trying to automate certificate generation with python3.cryptography; not having luck
我正在尝试以编程方式创建供 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 变体和我的自动化变体。他们看起来和我几乎一模一样。但是,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.
另一个来源指出的问题是,我使用与生成证书相同的密钥签署新证书。就像问题名称与颁发证书的名称相同一样,签名密钥应该是同一颁发证书的私钥。用类似的东西替换签名条款:
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()
)
我正在尝试以编程方式创建供 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 变体和我的自动化变体。他们看起来和我几乎一模一样。但是,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.
另一个来源指出的问题是,我使用与生成证书相同的密钥签署新证书。就像问题名称与颁发证书的名称相同一样,签名密钥应该是同一颁发证书的私钥。用类似的东西替换签名条款:
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()
)