1

I use python cryptography package to create a CRL object. But I need to convert this object into PEM format. In their documentation they don't seem to have an opposite of deserialization operation x509.load_pem_x509_crl. At the end of the codes below, how do I convert "crl" to PEM. Any idea?

from cryptography import x509
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.x509.oid import NameOID
import datetime
one_day = datetime.timedelta(1, 0, 0)
private_key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=2048,
)
builder = x509.CertificateRevocationListBuilder()
builder = builder.issuer_name(x509.Name([
    x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io CA'),
]))
builder = builder.last_update(datetime.datetime.today())
builder = builder.next_update(datetime.datetime.today() + one_day)
revoked_cert = x509.RevokedCertificateBuilder().serial_number(
    333
).revocation_date(
    datetime.datetime.today()
).build()
builder = builder.add_revoked_certificate(revoked_cert)
crl = builder.sign(
    private_key=private_key, algorithm=hashes.SHA256(),
)
# how to convert crl to PEM?
Lenny
  • 13
  • 3

1 Answers1

2

The CertificateRevocationListBuilder#sign() method returns a CertificateRevocationList object whose public_bytes() method can be used to perform serialization.

Deserialization is done with x509.load_pem_x509_crl().

Example:

...

# Serialize
from cryptography.hazmat.primitives import serialization
pem = crl.public_bytes(encoding=serialization.Encoding.PEM)
print(pem.decode('utf8'))

# Deserialize
from cryptography import x509
crl = x509.load_pem_x509_crl(pem)
pem = crl.public_bytes(encoding=serialization.Encoding.PEM) # Check
print(pem.decode('utf8')) 

with e.g. the following output:

-----BEGIN X509 CRL-----
MIIBfDBmAgEBMA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNVBAMMEmNyeXB0b2dyYXBo
eS5pbyBDQRcNMjEwOTExMDg0OTI3WhcNMjEwOTEyMDg0OTI3WjAVMBMCAgFNFw0y
MTA5MTEwODQ5MjdaMA0GCSqGSIb3DQEBCwUAA4IBAQCmO+pCzndqgeZBgfMNUsk4
SSVQg+lJ5WPm/cpFiR2UtKkwjKb60Gy4/zTDULojQVCzSdHfEUd+84JNMRzXrAqO
OEIr9S1xcyR3zrDVyciJOqxNxx+bMo0mpj4B7LMo3X4Xt02WZZEFuEwf7aICKl2r
uuas6HQ/jEtwRiEGFLeBN5+TcB5qW+ri/hNLJbfFRBoGSB6mvIysxgDi+7/6EIQn
H5o8H8AD5BoQ28jtB9H9u2JX5/oJivWorpiVFd2oOaNx2frc7Emchz0a7G9LpL3H
qS3QyRJyXqgRPXloFiKhOBRoO7lORGs+92pSBAwYaaWm38mmetzkBKIhMY8dWN4M
-----END X509 CRL-----

-----BEGIN X509 CRL-----
MIIBfDBmAgEBMA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNVBAMMEmNyeXB0b2dyYXBo
eS5pbyBDQRcNMjEwOTExMDg0OTI3WhcNMjEwOTEyMDg0OTI3WjAVMBMCAgFNFw0y
MTA5MTEwODQ5MjdaMA0GCSqGSIb3DQEBCwUAA4IBAQCmO+pCzndqgeZBgfMNUsk4
SSVQg+lJ5WPm/cpFiR2UtKkwjKb60Gy4/zTDULojQVCzSdHfEUd+84JNMRzXrAqO
OEIr9S1xcyR3zrDVyciJOqxNxx+bMo0mpj4B7LMo3X4Xt02WZZEFuEwf7aICKl2r
uuas6HQ/jEtwRiEGFLeBN5+TcB5qW+ri/hNLJbfFRBoGSB6mvIysxgDi+7/6EIQn
H5o8H8AD5BoQ28jtB9H9u2JX5/oJivWorpiVFd2oOaNx2frc7Emchz0a7G9LpL3H
qS3QyRJyXqgRPXloFiKhOBRoO7lORGs+92pSBAwYaaWm38mmetzkBKIhMY8dWN4M
-----END X509 CRL-----
Topaco
  • 40,594
  • 4
  • 35
  • 62
  • Thank you. Your solution worked. As for the deserialization of a PEM certificate, why did the following code works in one ubuntu machine A but not the other ubuntu machine B, which complains about missing one argument? with open(pemCrt, 'rb') as f: buf =f.read() cert = x509.load_pem_x509_certificate(buf) according to documentation, the backend argument is optional. If I do from cryptography.hazmat.backends import default_backend cert = x509.load_pem_x509_certificate(buf, default_backend()) it complains about buffer format, although it's from a perfect PEM file. Any idea? – Lenny Sep 14 '21 at 04:56
  • Regarding the 1st part: As of version 3.1, the backend argument is optional, see [Backends](https://cryptography.io/en/latest/hazmat/backends/#backends). I guess that the Cryptography versions on both Ubuntu machines are different and one version is older than 3.1 and therefore the backend argument is needed. – Topaco Sep 14 '21 at 10:57
  • Regarding the 2nd part: This should actually work, s. the [`load_pem_x509_certificate()`](https://cryptography.io/en/3.0/x509/reference/#cryptography.x509.load_pem_x509_certificate) sample. There may be an issue with the PEM file after all. Perhaps it's a DER file that cannot be imported this way (but with `load_der_x509_certificate()`). If this doesn't help, please post a _**new** question with the complete code and a sample certificate_, as this is a new question and code is hard to read in comments. – Topaco Sep 14 '21 at 11:10
  • @Topaco what about the `CertificateSigningRequestBuilder()` how we can serialize it – Adam Strauss Dec 01 '22 at 12:35