The purpose of this article is to demonstrate how to create a CSR (Certificate Signing Request) with the Python programming language. A CSR is required when requesting an SSL Certificate from a CA (Certification Authority) and is a signed request by the private key in your asymmetric key pair.
If you are looking at where to purchase an SSL Certificate from, we recommend you start with The SSL Store.
Some utilities, tools, or languages will generate the key pair and the CSR all in one command. Using python, this article will demonstrate first how to create a key pair and second how to create a CSR from the private key in the key pair.
How to create an asymmetric public private key pair in Python
This example of creating a key pair in python will use the RSA algorithm, but other asymmetric algorithms could also be used.
- Import the rsa library from the cryptography module
- Generate the RSA private key with public_exponent=65537 and key size 2048. Note that the key size of 2048 is the smallest recommended key size.
from cryptography.hazmat.primitives.asymmetric import rsa # Generate the RSA private key key = rsa.generate_private_key( public_exponent=65537, key_size=2048, )
The private key material is now stored in the
key variable, ready to be passed as a parameter to the
sign method in the following section describing how to create a CSR.
How to create a CSR in Python
This example will demonstrate how to programmatically create a CSR with information about our public key, about who we are, and what domains this requested SSL certificate will be used for.
- Import required libraries from the cryptography module, including
- Build the CSR with the
CertificateSigningRequestBuilderwith the information detailed in the paragraph above.
- Add extensions to the CSR about the domains the certificate will be used for.
- Sign the CSR with the private key created in the section above.
from cryptography import x509 from cryptography.x509.oid import NameOID from cryptography.hazmat.primitives import hashes # Generate a CSR csr = x509.CertificateSigningRequestBuilder().subject_name(x509.Name([ # Provide various details about who we are. x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"), x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"Virginia"), x509.NameAttribute(NameOID.LOCALITY_NAME, u"Richmond"), x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"My Organization"), x509.NameAttribute(NameOID.COMMON_NAME, u"example.com"), ])).add_extension( x509.SubjectAlternativeName([ # Describe what sites we want this certificate for. x509.DNSName(u"example.com"), x509.DNSName(u"www.example.com"), ]), critical=False, # Sign the CSR with the private key. ).sign(key, hashes.SHA256())
Note that some CAs may not require that all SANs (Subject Alternative Names) be contained in the CSR, and may simply require that they be entered into a text field in the request form, along with the CSR.
This article has demonstrated how to use Python to create a CSR. Leave us a comment if you have any questions or would like to see more examples.