8.4 OPENSSL TO PYTHON AND BACK

EXERCISE 8.4: OPENSSL TO PYTHON AND BACK

Generate a CSR with Python and sign it with Openssl.

Generate a CSR with Openssl, open it in Python, and create a self-signed certificate from it.


Let’s first create a root-certificate for yilkalandnoah.com. Then we will use this root certificate to perform the operations listed inside of the question.

from cryptography import x509 
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes 
from cryptography.hazmat.primitives.asymmetric import ec 
from cryptography.x509.oid import NameOID
import datetime
one_year = datetime.timedelta(days=365) 
one_day = datetime.timedelta(days=1)
from cryptography.hazmat.primitives.serialization import Encoding,PrivateFormat, NoEncryption

private_key = ec.generate_private_key(
    curve=ec.SECP256K1(), 
    backend=default_backend(),
)
private_bytes = private_key.private_bytes(
    Encoding.PEM, 
    format=PrivateFormat.TraditionalOpenSSL, 
    encryption_algorithm=NoEncryption(),
)

with open('data53_private_key.pem', 'wb') as f: 
    f.write(private_bytes)

print(private_bytes.decode())
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIJIvqQRCLySfM8W7RDyQB/QQnZsd85FtuGU3dtzqu727oAcGBSuBBAAK
oUQDQgAEyfWWuYkPirJb7yiTd0K5mDWpYKKfwnar71oeFUcphMWHk2/DxpyTVNZL
t9gOn54P7Ht8zqK7NuTDV26NI9lkHg==
-----END EC PRIVATE KEY-----
from cryptography.hazmat.primitives.serialization import PublicFormat

public_key = private_key.public_key() 
public_bytes = public_key.public_bytes(Encoding.PEM, PublicFormat.SubjectPublicKeyInfo) 

with open('data53_public_key.pem', 'wb') as f: 
    f.write(public_bytes)

print(public_bytes.decode())
-----BEGIN PUBLIC KEY-----
MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEyfWWuYkPirJb7yiTd0K5mDWpYKKfwnar
71oeFUcphMWHk2/DxpyTVNZLt9gOn54P7Ht8zqK7NuTDV26NI9lkHg==
-----END PUBLIC KEY-----
certificate = x509.CertificateBuilder(
    subject_name=x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, 'yilkalandnoah.com')]),
    issuer_name=x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, 'yilkalandnoah.com')]),
    not_valid_before=datetime.datetime.today() - one_day, 
    not_valid_after=datetime.datetime.today() + (one_year * 30), 
    serial_number=x509.random_serial_number(),
    public_key=public_key, 
).sign(
    private_key=private_key,
    algorithm=hashes.SHA256(),
    backend=default_backend(),
)
certificate_bytes = certificate.public_bytes(Encoding.PEM)

with open('data53_root_cert.crt', 'wb') as f: 
    f.write(certificate_bytes)

print(certificate_bytes.decode())
-----BEGIN CERTIFICATE-----
MIIBNTCB3aADAgECAhQUJTEt0N0BcNzd6W9KKOVr8YRLYTAKBggqhkjOPQQDAjAc
MRowGAYDVQQDDBF5aWxrYWxhbmRub2FoLmNvbTAgFw0yNDEwMjgwNzI5MjhaGA8y
MDU0MTAyMjA3MjkyOFowHDEaMBgGA1UEAwwReWlsa2FsYW5kbm9haC5jb20wVjAQ
BgcqhkjOPQIBBgUrgQQACgNCAATJ9Za5iQ+KslvvKJN3QrmYNalgop/CdqvvWh4V
RymExYeTb8PGnJNU1ku32A6fng/se3zOors25MNXbo0j2WQeMAoGCCqGSM49BAMC
A0cAMEQCIA5IV1lzECrC+ypZXS0++YEtLkYdqLqKsEk5e4cLT1vTAiB0wVg5OI2/
4lYYxPa9KWQYOrCE6Gb0qhVPlXlv7932nw==
-----END CERTIFICATE-----

Running: openssl x509 -in data53_root_cert.crt -text gives us:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            14:25:31:2d:d0:dd:01:70:dc:dd:e9:6f:4a:28:e5:6b:f1:84:4b:61
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: CN = yilkalandnoah.com
        Validity
            Not Before: Oct 28 07:29:28 2024 GMT
            Not After : Oct 22 07:29:28 2054 GMT
        Subject: CN = yilkalandnoah.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:c9:f5:96:b9:89:0f:8a:b2:5b:ef:28:93:77:42:
                    b9:98:35:a9:60:a2:9f:c2:76:ab:ef:5a:1e:15:47:
                    29:84:c5:87:93:6f:c3:c6:9c:93:54:d6:4b:b7:d8:
                    0e:9f:9e:0f:ec:7b:7c:ce:a2:bb:36:e4:c3:57:6e:
                    8d:23:d9:64:1e
                ASN1 OID: secp256k1
    Signature Algorithm: ecdsa-with-SHA256
    Signature Value:
        30:44:02:20:0e:48:57:59:73:10:2a:c2:fb:2a:59:5d:2d:3e:
        f9:81:2d:2e:46:1d:a8:ba:8a:b0:49:39:7b:87:0b:4f:5b:d3:
        02:20:74:c1:58:39:38:8d:bf:e2:56:18:c4:f6:bd:29:64:18:
        3a:b0:84:e8:66:f4:aa:15:4f:95:79:6f:ef:dd:f6:9f
-----BEGIN CERTIFICATE-----
MIIBNTCB3aADAgECAhQUJTEt0N0BcNzd6W9KKOVr8YRLYTAKBggqhkjOPQQDAjAc
MRowGAYDVQQDDBF5aWxrYWxhbmRub2FoLmNvbTAgFw0yNDEwMjgwNzI5MjhaGA8y
MDU0MTAyMjA3MjkyOFowHDEaMBgGA1UEAwwReWlsa2FsYW5kbm9haC5jb20wVjAQ
BgcqhkjOPQIBBgUrgQQACgNCAATJ9Za5iQ+KslvvKJN3QrmYNalgop/CdqvvWh4V
RymExYeTb8PGnJNU1ku32A6fng/se3zOors25MNXbo0j2WQeMAoGCCqGSM49BAMC
A0cAMEQCIA5IV1lzECrC+ypZXS0++YEtLkYdqLqKsEk5e4cLT1vTAiB0wVg5OI2/
4lYYxPa9KWQYOrCE6Gb0qhVPlXlv7932nw==
-----END CERTIFICATE-----

Part 1 of the question

Generate a CSR with Python and sign it with Openssl.

Step 1: Generate a CSR with Python

builder = x509.CertificateSigningRequestBuilder()
builder = builder.subject_name(
    name=x509.Name([
        x509.NameAttribute(NameOID.COMMON_NAME, 'solar.yilkalandnoah.com'),
    ])
)
builder = builder.add_extension(
    x509.BasicConstraints(ca=False, path_length=None),
    critical=True,
)
private_key2 = ec.generate_private_key(
    curve=ec.SECP256K1(),
    backend=default_backend(),
)
csr = builder.sign(
    private_key=private_key2, 
    algorithm=hashes.SHA256(),
    backend=default_backend(),
)
with open('solar_yn.csr', 'wb') as f: 
    f.write(csr.public_bytes(Encoding.PEM))

Step 2: Sign the CSR with Openssl

I signed it with the following command:

openssl x509 -req\
 -days 365\
 -in solar_yn.csr\
 -CAkey data53_private_key.pem\
 -CA data53_root_cert.crt\
 -out solar_yn.crt\
 -set_serial 123456789\
 -extfile v3.ext

Running the command: openssl x509 -in solar_yn.crt -text, will give us the following output:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 123456789 (0x75bcd15)
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: CN = yilkalandnoah.com
        Validity
            Not Before: Oct 29 05:56:21 2024 GMT
            Not After : Oct 29 05:56:21 2025 GMT
        Subject: CN = solar.yilkalandnoah.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:e5:8b:c1:37:34:ce:27:54:ba:db:27:a8:21:13:
                    6c:ee:70:e3:97:18:08:2e:f6:da:e7:e3:e2:34:6d:
                    eb:2d:32:11:05:db:db:b2:8b:00:85:12:66:e9:c7:
                    80:8c:06:d2:80:11:26:93:1d:19:e9:d8:55:74:38:
                    63:c8:cd:48:b9
                ASN1 OID: secp256k1
        X509v3 extensions:
            X509v3 Key Usage: 
                Digital Signature
            X509v3 Basic Constraints: 
                CA:FALSE
            X509v3 Subject Key Identifier: 
                89:88:EF:B5:BE:95:86:04:97:A9:E7:74:6A:FD:64:52:37:F2:86:83
            X509v3 Authority Key Identifier: 
                DirName:/CN=yilkalandnoah.com
                serial:14:25:31:2D:D0:DD:01:70:DC:DD:E9:6F:4A:28:E5:6B:F1:84:4B:61
    Signature Algorithm: ecdsa-with-SHA256
    Signature Value:
        30:45:02:21:00:96:2e:95:6e:5e:f8:2f:d1:e9:f1:75:f0:a2:
        be:46:da:bb:c1:c6:ea:02:7d:5a:a2:e0:7a:25:56:e1:90:ef:
        6a:02:20:23:12:49:32:66:0d:23:7e:4e:b6:02:c9:15:6e:e5:
        d6:02:ef:48:61:2f:dd:3c:30:02:3b:55:8c:b7:d5:91:36
-----BEGIN CERTIFICATE-----
MIIBqTCCAU+gAwIBAgIEB1vNFTAKBggqhkjOPQQDAjAcMRowGAYDVQQDDBF5aWxr
YWxhbmRub2FoLmNvbTAeFw0yNDEwMjkwNTU2MjFaFw0yNTEwMjkwNTU2MjFaMCIx
IDAeBgNVBAMMF3NvbGFyLnlpbGthbGFuZG5vYWguY29tMFYwEAYHKoZIzj0CAQYF
K4EEAAoDQgAE5YvBNzTOJ1S62yeoIRNs7nDjlxgILvba5+PiNG3rLTIRBdvbsosA
hRJm6ceAjAbSgBEmkx0Z6dhVdDhjyM1IuaN8MHowCwYDVR0PBAQDAgeAMAkGA1Ud
EwQCMAAwHQYDVR0OBBYEFImI77W+lYYEl6nndGr9ZFI38oaDMEEGA1UdIwQ6MDih
IKQeMBwxGjAYBgNVBAMMEXlpbGthbGFuZG5vYWguY29tghQUJTEt0N0BcNzd6W9K
KOVr8YRLYTAKBggqhkjOPQQDAgNIADBFAiEAli6Vbl74L9Hp8XXwor5G2rvBxuoC
fVqi4HolVuGQ72oCICMSSTJmDSN+TrYCyRVu5dYC70hhL908MAI7VYy31ZE2
-----END CERTIFICATE-----

Part 2 of the question

Generate a CSR with Openssl, open it in Python, and create a self-signed certificate from it.

Step 1: Generate the CSR with openssl

I created the CSR by using the following script:

# file: create_csr_using_openssl.sh
# generate the key first

openssl genpkey -algorithm RSA -out research_key.pem -pkeyopt rsa_keygen_bits:2048

# create a csr from the key

openssl req -new -key research_key.pem -out research_yn.csr

Step 2: create a CSR object in python

with open('research_yn.csr', 'rb') as f: 
    csr_bytes = f.read() 

csr = x509.load_pem_x509_csr(csr_bytes, default_backend())

Step 3: create a certificate from the CSR

research_cert_builder = x509.CertificateBuilder(
    subject_name=csr.subject,
    issuer_name=certificate.subject,
    not_valid_before=datetime.datetime.today() - one_day, 
    not_valid_after=datetime.datetime.today() + (one_day * 30), 
    serial_number=1122,
    public_key=csr.public_key(), 
)
research_cert_builder = research_cert_builder.add_extension(extval=x509.BasicConstraints(ca=False, path_length=None), critical=True)
research_cert = research_cert_builder.sign(
    private_key=private_key,
    algorithm=hashes.SHA256(),
    backend=default_backend(),
)
research_cert_bytes = research_cert.public_bytes(Encoding.PEM)

with open('research_cert.crt', 'wb') as f: 
    f.write(research_cert_bytes)

Running the command: openssl x509 -in research_cert.crt -text, will give us the following output:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1122 (0x462)
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: CN = yilkalandnoah.com
        Validity
            Not Before: Oct 28 09:23:15 2024 GMT
            Not After : Nov 28 09:23:15 2024 GMT
        Subject: C = ET, ST = Addis Ababa, O = Data53's Energy Company, CN = research.yilkalandnoah.com, emailAddress = research@yilkalandnoah.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:a8:e0:1e:a3:63:0b:07:5a:a0:d1:78:e0:71:8c:
                    45:32:b5:4c:35:cb:55:ee:8c:31:51:a5:84:af:70:
                    f5:de:bf:d3:48:9f:0d:0f:91:09:1a:8e:a5:f5:53:
                    2e:05:ff:19:5f:62:08:2a:dd:50:8c:25:38:87:08:
                    ac:f0:b0:ba:74:34:cf:02:70:d4:b5:ae:24:c6:25:
                    db:3b:c8:a9:46:75:b6:61:2d:f2:b2:42:56:ab:d6:
                    82:28:d4:c1:14:8b:a0:bf:1e:ac:18:14:0a:14:4e:
                    1e:8b:6f:dd:ec:78:13:fd:6d:a4:7f:88:b0:7f:09:
                    95:99:1d:3a:fc:00:b7:d3:a3:56:6b:73:eb:e5:09:
                    85:06:10:ee:17:e6:3b:3e:a2:b0:3a:92:fb:67:0f:
                    02:cb:8d:17:73:36:35:6f:af:80:9d:71:57:b3:57:
                    f6:e2:e6:f8:60:aa:ae:28:9d:de:ae:dd:dc:76:c6:
                    17:e9:08:e3:b6:6e:97:f8:54:54:cc:e8:b4:8c:43:
                    69:8e:6f:0f:03:73:18:77:e1:11:f4:7f:13:01:22:
                    d7:d3:fe:b3:49:17:cc:58:e8:e0:21:ab:b0:52:01:
                    b6:79:53:67:5b:63:89:3f:b7:67:01:e1:a8:25:d4:
                    a7:20:69:71:df:7a:4f:56:30:e2:88:0a:19:f7:29:
                    da:7f
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: critical
                CA:FALSE
    Signature Algorithm: ecdsa-with-SHA256
    Signature Value:
        30:44:02:20:48:3c:34:b9:76:d8:4d:d6:6e:34:4e:65:34:ab:
        7d:9b:47:a7:29:b5:42:f6:f6:b3:91:cb:d2:b4:2e:60:f3:a3:
        02:20:21:f6:c9:ef:e7:0d:26:21:ca:8b:3e:3f:55:aa:10:e6:
        7b:4f:a1:fd:4a:17:30:85:a2:9e:a2:e8:5f:0e:c4:34
-----BEGIN CERTIFICATE-----
MIICfDCCAiOgAwIBAgICBGIwCgYIKoZIzj0EAwIwHDEaMBgGA1UEAwwReWlsa2Fs
YW5kbm9haC5jb20wHhcNMjQxMDI4MDkyMzE1WhcNMjQxMTI4MDkyMzE1WjCBlTEL
MAkGA1UEBhMCRVQxFDASBgNVBAgMC0FkZGlzIEFiYWJhMSAwHgYDVQQKDBdEYXRh
NTMncyBFbmVyZ3kgQ29tcGFueTEjMCEGA1UEAwwacmVzZWFyY2gueWlsa2FsYW5k
bm9haC5jb20xKTAnBgkqhkiG9w0BCQEWGnJlc2VhcmNoQHlpbGthbGFuZG5vYWgu
Y29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqOAeo2MLB1qg0Xjg
cYxFMrVMNctV7owxUaWEr3D13r/TSJ8ND5EJGo6l9VMuBf8ZX2IIKt1QjCU4hwis
8LC6dDTPAnDUta4kxiXbO8ipRnW2YS3yskJWq9aCKNTBFIugvx6sGBQKFE4ei2/d
7HgT/W2kf4iwfwmVmR06/AC306NWa3Pr5QmFBhDuF+Y7PqKwOpL7Zw8Cy40XczY1
b6+AnXFXs1f24ub4YKquKJ3ert3cdsYX6Qjjtm6X+FRUzOi0jENpjm8PA3MYd+ER
9H8TASLX0/6zSRfMWOjgIauwUgG2eVNnW2OJP7dnAeGoJdSnIGlx33pPVjDiiAoZ
9ynafwIDAQABoxAwDjAMBgNVHRMBAf8EAjAAMAoGCCqGSM49BAMCA0cAMEQCIEg8
NLl22E3WbjROZTSrfZtHpym1Qvb2s5HL0rQuYPOjAiAh9snv5w0mIcqLPj9VqhDm
e0+h/UoXMIWinqLoXw7ENA==
-----END CERTIFICATE-----