smac89
9/26/2017 - 3:28 PM

Create a self-signed certificate for SSL encrypted http messaging

Create a self-signed certificate for SSL encrypted http messaging

def _gen_private_pem_key():
    from cryptography.hazmat.backends import default_backend as crypto_default_backend
    from cryptography.hazmat.primitives.asymmetric import rsa
    key = rsa.generate_private_key(
        backend=crypto_default_backend(),
        public_exponent=65537,
        key_size=2048
    )
    return key


# mostly derived from https://cryptography.io/en/latest/x509/tutorial/
def generate_signed_pem_pair():
    from cryptography.hazmat.primitives import serialization as crypto_serialization, hashes
    from cryptography.hazmat.backends import default_backend as crypto_default_backend
    from cryptography import x509
    from cryptography.x509.oid import NameOID
    from collections import namedtuple
    import datetime
    import uuid

    key = _gen_private_pem_key()

    subject = issuer = x509.Name([
        x509.NameAttribute(NameOID.COUNTRY_NAME, u"CA"),
        x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"SK"),
        x509.NameAttribute(NameOID.LOCALITY_NAME, u"Saskatoon"),
        x509.NameAttribute(NameOID.ORGANIZATION_NAME, unicode(str(uuid.uuid4()), 'utf-8')),
        x509.NameAttribute(NameOID.COMMON_NAME, u"Prairies")
    ])

    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(
            # The certificate will be valid for an hour
            datetime.datetime.utcnow() + datetime.timedelta(hours=1)
        ).add_extension(
            x509.SubjectAlternativeName([x509.DNSName(u'localhost')]),
            critical=False
        ).sign(
            # Sign our certificate with our private key
            key, hashes.SHA256(), crypto_default_backend()
    )

    PemPair = namedtuple('PemPair', ['key', 'cert'])
    return PemPair(key=lambda: key.private_bytes(
        crypto_serialization.Encoding.PEM,
        crypto_serialization.PrivateFormat.TraditionalOpenSSL,
        crypto_serialization.NoEncryption()), cert=lambda: cert.public_bytes(crypto_serialization.Encoding.PEM))
  
if __name__ == '__main__':
    signed_pair = generate_signed_pem_pair()
    print signed_pair.key()
    print signed_pair.cert()

    # That is all folks