How to create a public-key infrastructure
Say Alice generates her private key, and extracts her public key:
openssl genrsa -out alice_priv_key.pem 2048 openssl rsa -pubout -in alice_priv_key.pem -out alice_pub_key.pem
Alice then distributes her public key, saying:
Here’s my public key! Please use it to send me messages and to verify that future messages are from me.
-----BEGIN PUBLIC KEY----- MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALdRf5ibmHxq8ggNQ3a+N3v1TjFxAcsO bD9d6x5Klyo5vfKQ9/HjVwyVgJS8lt7vdHd3NAqU0jID8wCs+htkFl8CAwEAAQ== -----END PUBLIC KEY-----
If Bob receives this message in his email inbox, can he trust it? No! It could be from anyone! Nothing in the message demonstrates that this email is really from the person that Bob knows as Alice.
One way for Alice to convince Bob that this is her public key is to deliver the key in person. Alice can visit Bob’s house and hand him the public key on paper.
This method is inconvenient, because Bob lives in London and Alice in Moscow. But Alice knows that Bob trusts her friend Pyotr, and that Bob has Pyotr’s public key. So Alice asks Pyotr to sign her public key. So Pyotr does this:
cat <(echo 'This public key is Alice <firstname.lastname@example.org>:') alice_pub_key.pem > statement_by_pyotr $ openssl rsautl -sign -in statement_by_pyotr -inkey pyotr_priv_key.pem -out certificate
Pyotr calls this signed public key a “certificate”. Alice can now embed this certificate in her email to Bob instead:
Here’s my public key! Please use it to send me messages and to verify that future messages are from me. I’ve attached my key in the file
certificate, which is signed by Pyotr.
Now when Bob receives this email, he can verify the attached
certificate file to get Alice’s public key:
$ openssl rsautl -verify -in certificate -inkey pyotr_pub_key.pem -pubin This public key is Alice <email@example.com>: -----BEGIN PUBLIC KEY----- MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALdRf5ibmHxq8ggNQ3a+N3v1TjFxAcsO bD9d6x5Klyo5vfKQ9/HjVwyVgJS8lt7vdHd3NAqU0jID8wCs+htkFl8CAwEAAQ== -----END PUBLIC KEY-----
In this scheme, Pyotr is acting as a certificate authority (CA). Because Pyotr is trusted by Bob, Pyotr can perform a valuable service for Alice: vouching for Alice’s public key.
In the real world, the certificate authorities are Comodo, Symantec, GoDaddy, and others. Comodo has gotten its public key onto many people’s machines, in the form of “root certificates”. Comodo can therefore perform a valuable service to websites: vouching for that website’s public key, so that other people can communicate with that website. Instead of visiting someone’s house to tie the public key to a real person, Comodo will tie the public key to a domain by verifying ownership of the domain (e.g. with a DNS challenge). Instead of ad hoc signed strings, Comodo and others use X.509, which has proper formats for certificates (amongst other features).
In future posts I’ll look at the
ca commands, which are the “proper” way to do PKI.
I wrote this because I'm learning SSL/TLS. x509 is a big part of this, but the tools obscure the problems it solves, and the cryptographic operations involved. To understand it, I'm building it myself. This post is not associated with my employer. This site is hosted by Netlify (who are great, but I'm not associated with them either).