-
-
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 |
Thanks for this gist. I needed a CA for testing and this saved me figuring all of this out :)
Oh boy, this is an old one. Glad it helped! 🫂
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
Thanks for this gist. I needed a CA for testing and this saved me figuring all of this out :)