Coding Like a Certificate Authority
00:08 In this lesson, you’ll switch roles—become Alice—and create a CSR and then switch roles back to Charlie, signing the CSR. Here’s a quick review. Charlie, the Certificate Authority, needs a public key, which you’ve created, a private key, which you’ve created, and the ability to sign CSRs. Alice, the site owner, needs a public key, a private key, and a Certificate Signing Request describing her site that she can submit to the CA. Now, you’re going to change roles.
00:41 You’re acting as Alice, and you’re going to create a Certificate Signing Request so that you can ask Charlie to sign it. In order to do this, Alice needs a private key and a list of hostnames to be associated with the certificate.
CSR will also be built in a class using a factory pattern similar to the key patterns. This factory will require a list of hostnames that are valid for the key, information about the subject, and needs to be signed by Alice’s private key.
01:16 Like the public and private key, you’ll also need a mechanism for saving the CSR to a PEM file so it can be sent to the CA. Finally, all of this will be combined together into that single key generating script, which will go through all of the steps in the process.
This is the definition of the
CSR object. It’s similar to the
PublicKey object. It has a
.generate() factory method, which takes a private key, a list of hostnames, and a dictionary of subject information. Because it’s a certificate—just like the public key—you need to create subject information, reusing the
The resulting certificate from the CA has to be signed against a list of hostnames it’s valid for, so the CSR has to contain that information for the CA to approve. Lines 15 through 19 loops through a list of hosts and uses the
SubjectAlternativeName object from
x509 to create a list of those names.
Similar to the
PublicKey, a builder factory is used. This time, it’s a
CSR builder. The subject for the certificate is included, as well as the alt names provided above, containing the hostnames. Finally, an empty
CSR object is created.
It is then returned to the caller. Because the output of the
CSR is the same kind of certificate as a public key, instead of reimplementing the
.save() method, I’ve just inherited from the
PublicKey class and overloaded the
Once again, I’m back inside of the
generate_keys file. In this section, you’re acting as Alice with the intent of creating a CSR. In order to do that, you first need a private key. Line 25 and 26 generates a
PrivateKey. This is no different than the one for the CA, but this one is for Alice. The key is being saved in
"server-private-key.pem", and there’s a different password assigned because Alice doesn’t know the CA’s password. Take careful note of this. In the next lesson when you go to use this key, you’re going to need to know this password. Lines 29 through 36 populates information for the CSR. First, the name dictionary.
This names Alice’s company and the host
"alice.example.net" where she would like to host an HTTPS server. The
alt_names list contains the list of servers that will be valid for this certificate. In this case,
If you’re self-signing certificates for internal use, you may only need
'localhost' in this situation. This is something else I want you to take careful note of. In lesson seven, when you go to use this, these hostnames will become important. Finally, the meat of it: line 38 and 39 generates the actual Certificate Signing Request.
It requires Alice’s
server_private_key, the list of hostnames in
alt_names, and the location information in the
name_dict. Following the same pattern as before, the object is generated, and then the
.save() method is called—this time, saving it in a PEM file called
This is the contents of that PEM file. Doesn’t look much different. Once again, it’s a large ASCII blob of certificate information. The header, here, is the
CERTIFICATE REQUEST, indicating that this is a CSR.
In addition to the CSR PEM that Alice submits to Charlie, Charlie also needs her public key and private key. You’re going to need to add a
.load() method to the
CSR object class to load in the PEM file, and then create a
SignedKey object will also need a method for writing this certificate to a PEM file. Once all this is done, the final step will be use the
SignedKey object inside of the key generating script to finish off the whole process.
This file defines the
SignedKey object. Similar to the
CSR object, it inherits from
PublicKey. This is because, once again, it’s issuing a certificate and can use the inherited
.save() method. Using the pattern you’re now familiar with, there is a class method called
.generate(), which acts as the factory. This also uses the
make_builder() helper utility.
06:29 The only difference here is—because this is for a CA—the subject and the issuer are different. The subject is the subject from the CSR, and the issuer is the subject information from the CA’s public key.
The builder factory is used to sign the actual certificate. The signature on the certificate comes from the CA’s private key. The builder returns the result, and—like before—this is stored on the
.key attribute of the object created and the factory method returns the object.
08:00 And all of that work was to produce this one certificate. This is the certificate for Alice’s server. She can now host HTTPS and anyone with a browser that has Charlie listed as a CA will consider her site secure.
That was a lot of code in a lot of different files, so here’s a bit of a recap. The
generate_keys file is a single program that acts as both Alice and Charlie—creating the appropriate keys, a CSR, and signing that CSR so Alice can use it. First off, a private key was created, stored in the file
ca-private-key.pem, which is Charlie the CA’s private key. Secondly, a public key was created, stored in
08:59 It was signed and submitted to Charlie. Charlie takes the CSR and creates a new certificate, which is a public certificate that has been signed by Charlie the CA. Alice can now use this to run TLS on her web server.
Become a Member to join the conversation.