-
-
Save major/8ac9f98ae8b07f46b208 to your computer and use it in GitHub Desktop.
| from cryptography import x509 | |
| from cryptography.hazmat.backends import default_backend | |
| from cryptography.hazmat.primitives import hashes, serialization | |
| from cryptography.hazmat.primitives.asymmetric import rsa | |
| from cryptography.x509.oid import NameOID | |
| import datetime | |
| import uuid | |
| one_day = datetime.timedelta(1, 0, 0) | |
| private_key = rsa.generate_private_key( | |
| public_exponent=65537, | |
| key_size=2048, | |
| backend=default_backend() | |
| ) | |
| public_key = private_key.public_key() | |
| builder = x509.CertificateBuilder() | |
| builder = builder.subject_name(x509.Name([ | |
| x509.NameAttribute(NameOID.COMMON_NAME, u'openstack-ansible Test CA'), | |
| x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'openstack-ansible'), | |
| x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, u'Default CA Deployment'), | |
| ])) | |
| builder = builder.issuer_name(x509.Name([ | |
| x509.NameAttribute(NameOID.COMMON_NAME, u'openstack-ansible Test CA'), | |
| ])) | |
| builder = builder.not_valid_before(datetime.datetime.today() - one_day) | |
| builder = builder.not_valid_after(datetime.datetime(2018, 8, 2)) | |
| builder = builder.serial_number(int(uuid.uuid4())) | |
| builder = builder.public_key(public_key) | |
| builder = builder.add_extension( | |
| x509.BasicConstraints(ca=True, path_length=None), critical=True, | |
| ) | |
| certificate = builder.sign( | |
| private_key=private_key, algorithm=hashes.SHA256(), | |
| backend=default_backend() | |
| ) | |
| print(isinstance(certificate, x509.Certificate)) | |
| with open("ca.key", "wb") as f: | |
| f.write(private_key.private_bytes( | |
| encoding=serialization.Encoding.PEM, | |
| format=serialization.PrivateFormat.TraditionalOpenSSL, | |
| encryption_algorithm=serialization.BestAvailableEncryption(b"openstack-ansible") | |
| )) | |
| with open("ca.crt", "wb") as f: | |
| f.write(certificate.public_bytes( | |
| encoding=serialization.Encoding.PEM, | |
| )) |
| $ openssl asn1parse -in ca.crt | |
| 0:d=0 hl=4 l= 801 cons: SEQUENCE | |
| 4:d=1 hl=4 l= 521 cons: SEQUENCE | |
| 8:d=2 hl=2 l= 3 cons: cont [ 0 ] | |
| 10:d=3 hl=2 l= 1 prim: INTEGER :02 | |
| 13:d=2 hl=2 l= 16 prim: INTEGER :7024B38452CF480FBA3E5DF5937A1B58 | |
| 31:d=2 hl=2 l= 13 cons: SEQUENCE | |
| 33:d=3 hl=2 l= 9 prim: OBJECT :sha256WithRSAEncryption | |
| 44:d=3 hl=2 l= 0 prim: NULL | |
| 46:d=2 hl=2 l= 36 cons: SEQUENCE | |
| 48:d=3 hl=2 l= 34 cons: SET | |
| 50:d=4 hl=2 l= 32 cons: SEQUENCE | |
| 52:d=5 hl=2 l= 3 prim: OBJECT :commonName | |
| 57:d=5 hl=2 l= 25 prim: UTF8STRING :openstack-ansible Test CA | |
| 84:d=2 hl=2 l= 30 cons: SEQUENCE | |
| 86:d=3 hl=2 l= 13 prim: UTCTIME :151111141635Z | |
| 101:d=3 hl=2 l= 13 prim: UTCTIME :180802000000Z | |
| 116:d=2 hl=2 l= 96 cons: SEQUENCE | |
| 118:d=3 hl=2 l= 34 cons: SET | |
| 120:d=4 hl=2 l= 32 cons: SEQUENCE | |
| 122:d=5 hl=2 l= 3 prim: OBJECT :commonName | |
| 127:d=5 hl=2 l= 25 prim: UTF8STRING :openstack-ansible Test CA | |
| 154:d=3 hl=2 l= 26 cons: SET | |
| 156:d=4 hl=2 l= 24 cons: SEQUENCE | |
| 158:d=5 hl=2 l= 3 prim: OBJECT :organizationName | |
| 163:d=5 hl=2 l= 17 prim: UTF8STRING :openstack-ansible | |
| 182:d=3 hl=2 l= 30 cons: SET | |
| 184:d=4 hl=2 l= 28 cons: SEQUENCE | |
| 186:d=5 hl=2 l= 3 prim: OBJECT :organizationalUnitName | |
| 191:d=5 hl=2 l= 21 prim: UTF8STRING :Default CA Deployment | |
| 214:d=2 hl=4 l= 290 cons: SEQUENCE | |
| 218:d=3 hl=2 l= 13 cons: SEQUENCE | |
| 220:d=4 hl=2 l= 9 prim: OBJECT :rsaEncryption | |
| 231:d=4 hl=2 l= 0 prim: NULL | |
| 233:d=3 hl=4 l= 271 prim: BIT STRING | |
| 508:d=2 hl=2 l= 19 cons: cont [ 3 ] | |
| 510:d=3 hl=2 l= 17 cons: SEQUENCE | |
| 512:d=4 hl=2 l= 15 cons: SEQUENCE | |
| 514:d=5 hl=2 l= 3 prim: OBJECT :X509v3 Basic Constraints | |
| 519:d=5 hl=2 l= 1 prim: BOOLEAN :255 | |
| 522:d=5 hl=2 l= 5 prim: OCTET STRING [HEX DUMP]:30030101FF | |
| 529:d=1 hl=2 l= 13 cons: SEQUENCE | |
| 531:d=2 hl=2 l= 9 prim: OBJECT :sha256WithRSAEncryption | |
| 542:d=2 hl=2 l= 0 prim: NULL | |
| 544:d=1 hl=4 l= 257 prim: BIT STRING |
Hello, I am trying to create a root certificate, your code works fine.
But I need to add additional extensions (when using openssl these extensions are described in the configuration file):
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
I add it like this:
builder.add_extension(
x509.AuthorityKeyIdentifier(aki.key_identifier,
authority_cert_issuer=None,
authority_cert_serial_number=None),
critical=False,
)
I can't figure out how to get authority_cert_issuer and authority_cert_serial_number.
If I create a certificate using openssl, I can see the extensions when viewing the certificate:
X509v3 Authority Key Identifier:
keyid:56:D6:4A:1E:1B:CD:25:62:6C:F2:BB:63:37:2B:1C:09:96:9D:21:11
DirName:/C=RU/ST=Saint-Petersburg/L=Saint-Petersburg/O=LABICS/[email protected]/CN=Example Certificate Authority
serial:07:5E:20:63:B0:B1:68:30:39:FE:A2:6A:4C:69:08:64:5A:A7:0C:A6
How can I get the same result using cryptography?
Please help me to understand.
I can't figure out how to get authority_cert_issuer and authority_cert_serial_number.
https://github.com/search?q=repo%3Apyca%2Fcryptography%20x509.AuthorityKeyIdentifier
For those looking to create ca.key without a password, i.e. store the actual private key without encryption, which is likely needed if you say want to use this in a system which does not expose a feature to decrypt via a password, you can call serliazation.NoEncryption() instead of serialization.BestEncryptionAvailable(b"openstack-ansible"). And yes this code still works just fine on 3.11 🙏
Oh boy, this is an old one. Glad it helped! 🫂