How to generate a certificate using pyOpenSSL to make it secure connection?

Петр Друбов picture Петр Друбов · May 18, 2017 · Viewed 7.8k times · Source

I generate self-signed-cert

CA_KEY_FILE = os.path.join(settings.ROOT_CRT_PATH, 'rootCA.key')
CA_CERT_FILE = os.path.join(settings.ROOT_CRT_PATH, 'rootCA.crt')


def create_self_signed_cert_root(cleanned_data):
k = crypto.PKey()
k.generate_key(crypto.TYPE_RSA, 2048)

cert = crypto.X509()

cert.get_subject().C = cleanned_data['country']
cert.get_subject().ST = cleanned_data['state']
cert.get_subject().L = cleanned_data['location']
cert.get_subject().O = cleanned_data['organization']
if cleanned_data['organizational_unit_name']:
    cert.get_subject().OU = cleanned_data['organizational_unit_name']
cert.get_subject().CN = cleanned_data['cn']
if cleanned_data['email']:
    cert.get_subject().emailAddress = cleanned_data['email']

cert.set_serial_number(1000)
cert.gmtime_adj_notBefore(0)
cert.gmtime_adj_notAfter(5 * 365 * 24 * 60 * 60)
cert.set_issuer(cert.get_subject())
cert.set_pubkey(k)
cert.sign(k, 'sha256')

key_path = os.path.join(settings.MEDIA_ROOT, CA_KEY_FILE)
cert_path = os.path.join(settings.MEDIA_ROOT, CA_CERT_FILE)

if not os.path.exists(os.path.join(settings.MEDIA_ROOT, settings.ROOT_CRT_PATH)):
    os.mkdir(os.path.join(settings.MEDIA_ROOT, settings.ROOT_CRT_PATH))

with open(cert_path, 'wb') as f:
    f.write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert))

with open(key_path, 'wb') as f:
    f.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, k))

After that I generate a certificate signed by the first certificate

def create_signed_cert(cn):
ca_cert = crypto.load_certificate(crypto.FILETYPE_PEM, open(os.path.join(settings.MEDIA_ROOT, CA_CERT_FILE)).read())

ca_key = crypto.load_privatekey(crypto.FILETYPE_PEM, open(os.path.join(settings.MEDIA_ROOT, CA_KEY_FILE)).read())

k = crypto.PKey()
k.generate_key(crypto.TYPE_RSA, 2048)

cert = crypto.X509()

cert.get_subject().C = models.RootCrt.objects.first().country
cert.get_subject().ST = models.RootCrt.objects.first().state
cert.get_subject().L = models.RootCrt.objects.first().location
cert.get_subject().O = models.RootCrt.objects.first().organization
if models.RootCrt.objects.first().organizational_unit_name:
    cert.get_subject().OU = models.RootCrt.objects.first().organizational_unit_name
cert.get_subject().CN = cn
if models.RootCrt.objects.first().email:
    cert.get_subject().emailAddress = models.RootCrt.objects.first().email

cert.set_serial_number(1000)
cert.gmtime_adj_notBefore(0)
cert.gmtime_adj_notAfter(5 * 365 * 24 * 60 * 60)
cert.set_issuer(ca_cert.get_subject())
cert.set_pubkey(k)
cert.sign(ca_key, 'sha256')

if not os.path.exists(os.path.join(settings.MEDIA_ROOT, cn)):
    os.mkdir(os.path.join(settings.MEDIA_ROOT, cn))

with open(os.path.join(settings.MEDIA_ROOT, cn, cn + '.crt'), 'wb') as f:
    f.write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert))

with open(os.path.join(settings.MEDIA_ROOT, cn, cn + '.key'), 'wb') as f:
    f.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, k))

But it does not work. After importing root certificate into the browser, I still get an insecure connection. If I do it through the OpenSSL, then everything will work.

openssl genrsa -out rootCA.key 2048
openssl req -x509 -new -key rootCA.key -days 10000 -out rootCA.crt
openssl genrsa -out server101.mycloud.key 2048
openssl req -new -key server101.mycloud.key -out server101.mycloud.csr
openssl x509 -req -in server101.mycloud.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out server101.mycloud.crt -days 5000

I do not understand why the connection is insecure

Answer

Петр Друбов picture Петр Друбов · May 18, 2017

Decided the question. At first it was necessary to create a request, and after the certificate

def create_signed_cert(cn):
ca_cert = crypto.load_certificate(crypto.FILETYPE_PEM, open(os.path.join(settings.MEDIA_ROOT, CA_CERT_FILE)).read())

ca_key = crypto.load_privatekey(crypto.FILETYPE_PEM, open(os.path.join(settings.MEDIA_ROOT, CA_KEY_FILE)).read())

k = crypto.PKey()
k.generate_key(crypto.TYPE_RSA, 2048)

cert_req = crypto.X509Req()

cert_req.get_subject().C = models.RootCrt.objects.first().country
cert_req.get_subject().ST = models.RootCrt.objects.first().state
cert_req.get_subject().L = models.RootCrt.objects.first().location
cert_req.get_subject().O = models.RootCrt.objects.first().organization
if models.RootCrt.objects.first().organizational_unit_name:
    cert_req.get_subject().OU = models.RootCrt.objects.first().organizational_unit_name
cert_req.get_subject().CN = cn
if models.RootCrt.objects.first().email:
    cert_req.get_subject().emailAddress = models.RootCrt.objects.first().email

cert_req.set_pubkey(k)
cert_req.sign(ca_key, 'sha256')

cert = crypto.X509()
cert.gmtime_adj_notBefore(0)
cert.gmtime_adj_notAfter(5 * 365 * 24 * 60 * 60)
cert.set_issuer(ca_cert.get_subject())
cert.set_subject(cert_req.get_subject())
cert.set_pubkey(cert_req.get_pubkey())
cert.sign(ca_key, 'sha256')