Creating self-signed SSL certificates

Create a self-signed SSL certificate using openssl:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out certificate.pem -days 365 -nodes

OpenSSL will ask for Country Name, State or Province Name, Common Name and all that jazz before creating key and certificate.


Create a self-signed SSL certificate using python with the cryptography package:

#! /usr/bin/env python3

from cryptography import x509
 from cryptography.x509.oid import NameOID
 from cryptography.hazmat.primitives import serialization, hashes
 from cryptography.hazmat.primitives.asymmetric import rsa
 from cryptography.hazmat.backends import default_backend
 import datetime

name_attributes = []

country_name = input("COUNTRY_NAME: ")
 if(country_name != ""):
 name_attributes.append(x509.NameAttribute(NameOID.COUNTRY_NAME, country_name))

state_or_province_name = input("STATE_OR_PROVINCE_NAME: ")
 if(state_or_province_name != ""):
 name_attributes.append(x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, state_or_province_name))

locality_name = input("LOCALITY_NAME: ")
 if(locality_name != ""):
 name_attributes.append(x509.NameAttribute(NameOID.LOCALITY_NAME, locality_name))

organization_name = input("ORGANIZATION_NAME: ")
 if(organization_name != ""):
 name_attributes.append(x509.NameAttribute(NameOID.ORGANIZATION_NAME, organization_name))

common_name = input("COMMON_NAME: ")
 if(common_name != ""):
 name_attributes.append(x509.NameAttribute(NameOID.COMMON_NAME, common_name))

print("Enter SubjectAltName DNSName values, one at a time. Press Enter on an empty line to finish.")
 san_list = []
 san = "nonempty"
 while san != "":
 san = input("SAN DNSName: ")
 if san != "":
 san_list.append(x509.DNSName(san))

# Generate our key
 key = rsa.generate_private_key(
 public_exponent=65537,
 key_size=2048,
 backend=default_backend()
 )

# Write our key to disk for safe keeping
 with open("key.pem", "wb") as f:
 f.write(key.private_bytes(
 encoding=serialization.Encoding.PEM,
 format=serialization.PrivateFormat.TraditionalOpenSSL,
 encryption_algorithm=serialization.NoEncryption(),
 ))

# Various details about who we are. For a self-signed certificate the
 # subject and issuer are always the same.
 subject = issuer = x509.Name(name_attributes)

cert = x509.CertificateBuilder().subject_name(
 subject
 ).issuer_name(
 issuer
 ).public_key(
 key.public_key()
 ).serial_number(
 x509.random_serial_number()
 ).not_valid_before(
 datetime.datetime.utcnow()
 ).not_valid_after(
 # Our certificate will be valid for 365 days
 datetime.datetime.utcnow() + datetime.timedelta(days=365)
 )

# add SAN entries if any have been entered
 if san_list:
 cert = cert.add_extension(
 x509.SubjectAlternativeName(san_list),
 critical=False
 )

# Sign our certificate with our private key
 cert = cert.sign(key, hashes.SHA256(), default_backend())

# Write our certificate out to disk.
 with open("certificate.pem", "wb") as f:
 f.write(cert.public_bytes(serialization.Encoding.PEM))

The script will ask for Country Name, State or Province Name, Common Name and all that jazz before creating key and certificate. We even get to enter SubjectAlternativeName values! Great.