DEV Community

Anthony Dreessen
Anthony Dreessen

Posted on

Explain Certificates Like I'm Five

Wondering about the difference between certificates, private keys, and public keys and what the general model is for being able to offload most of that work to keychain or some other automated "code signing" entity

Top comments (7)

Collapse
 
nestedsoftware profile image
Nested Software • Edited

Asymmetric cryptography (also known as public key cryptography) has this very interesting property: You can create a pair of keys, and if you encrypt a message with one of the keys, you can then quickly decrypt the message with the other key. If you don't have the other key, you can't decrypt the message. The important thing is that if you have access to only one of the keys, there isn't any easy way to figure out what the other key is.

In practice, you choose one of the keys to be your "public" key. That means that you can publish it online and anyone can see it. You choose the other key to be your "private" key. You have to keep that one as safe as possible so that you're the only one with access to it. As far as I know there is no inherent difference between the two keys that are used. You just arbitrarily pick one to be the private key (or your encryption software does it for you).

If someone wants to send you a private message, they can use your public key to encrypt the message. That means only someone with the private key (hopefully that's only you) can decrypt the message to read it.

You can also encrypt a message with your private key and send it to someone else. That means they can decrypt the message with your public key. Since the public key is available to everyone, that means anybody can read your message. So how is this useful then? It's useful because if they can decrypt the message using your public key, they know for sure that your private key was used to encrypt it. In other words, they know that you (or someone with access to that private key at least) was the one who sent the message. Encrypting a message with the private key so that it can be decrypted with the public key is called "signing" a message.

Let's say I sign a message with my private key and send it to you. By decrypting the message with my public key, you know that my private key was used to generate the message. However, how do you know that the public key really belongs to me? Maybe someone just created a public key and published it to an online registry under my name so that they could impersonate me!

That's where certificates come in. Basically I can go to some organization, known as a certificate authority, and ask them to use their private key to sign my public key. Usually I would have to offer some evidence that I am who I say I am first (the amount of evidence needed can vary in practice). Once they are convinced that I am really me, they then sign my public key.

That’s what a certificate is: A certificate is someone's public key, let's say Janet's public key, along with some additional information such as name, address, organization, etc., that has been encrypted using the private key of a certificate authority. That means you can use the certificate authority's public key to decrypt the certificate. Doing so insures that the information contained therein was confirmed to be valid by the certificate authority and that no one has modified it -- if someone tried to tamper with the certificate, it would no longer be possible to decrypt it with the certificate authority's public key.

Now, when you get a signed message from Janet, you can verify that the public key needed to decrypt it was signed by a given authority. That gives you additional confidence that it's a message from the real Janet. Of course, now a new question may arise: How do you know that a given certificate authority is legitimate? It turns out there is a chain of authorities where the public key of each one is verified by one higher up above it. At the very top there is a "root certificate authority" that everyone has agreed to trust. As an example, the US federal government acts as a root authority for some public keys.

Collapse
 
pinwheeler profile image
Anthony Dreessen

when you say "signed by" does that mean "encrypted with the private key corresponding to the known public key for that entity"?

Collapse
 
nestedsoftware profile image
Nested Software • Edited

Yes, I believe so. From en.wikipedia.org/wiki/Public_key_c...

Signature: A signature of the certificate body by the issuer's private key.

Collapse
 
tux0r profile image
tux0r

Private/public keys are for encryption, e.g. GnuPG. The public key is what you give other people to sign messages to you, the private key is what you keep to decrypt them.

Certificates are for validating your authority, e.g. to make sure that yourdomain.com is yours or that a certain code commit was definitely made by you.

Collapse
 
pinwheeler profile image
Anthony Dreessen

how does a certificate validate your authority? In the case of a restricted git repo, how does one verify identity using a certificate? Where/when is the certificate "registered" w/r/t identity on the site?

Collapse
 
tailcall profile image
Maria Zaitseva

I really only know about TLS, so I'll explain how it works from TLS point of view. I believe this roughly applies to all digital certs systems.

A certificate is essentially a pair of private/public keys. It's split in halfs, public key part (with your domain name written in it) is sent to you. When establishing a TLS connection, server sends you some data encrypted with its private key. You decrypt it, and if decryption doesn't fail, you're (probably) talking to genuine owner of a certificate.

The funny part here is that a single certificate can't be considered trustworthy, somebody could probably hijack the connection and send you their own certificate instead of server's, and you'd never know. This is called a man-in-the-middle attack. That's where certificate authorities (CA) come into play.

Basically server owner just send their certificate for signing to a CA. Each CA has their own certificate which they use to sign other certificates. So now the server has to serve you not a single cert, but a certificate chain including CA's certificate. When you receive a server's certificate, you can always download CA's own certificate and validate a signature on a server's certificate—that makes man-in-the-middle attacks not feasible.

The funniest part is that CAs can have their certificates signed by yet another CA to enforce even more trust, so in fact you're likely to receive a pretty long certificate chain:

Server's cert ← CA1 cert ← CA2 cert ← CA3 cert

where ← means "is signed by".

CA3 cert obviously is not verified by anyone. It's a so-called root certificate and the issuer of this certificate must be pretty well trusted. Root certificates are usually bundled with OS distributions and web browsers. They're usually issued by some big serious companies, but there are also community-driven root CAs, like CAcert (see cacert.org).

Collapse
 
cjbrooks12 profile image
Casey Brooks

Certificates are all about trust. The data is public, not encrypted, but you still want some way to know that it was generated by a "good guy", and that it hasn't been tampered with.

For example, on github you may see commits as "verified". Commonly this is done on commits that Github themselves made, such as merging a pull request (whom you trust, because they're Github), or by someone that Github trusts. If you can't trust Github, then that "verified" badge realistically means nothing, because they, as a "bad guy" could have tampered with the commit, and you would still verify it successfully. But as long as Github can show that they're not tampering with commits, and that they're not compromised, then you can trust that a "verified" commit is exactly the change that it was intended to be by the creator.

This notion of trust comes down to cryptographic signatures. Basically, someone wanting to sign a commit will generate a pair of public and private keys, and then pass the commit through a tool like GPG, along with your private key. The result is a signature that can only be generated by the private key, and can only be verified by the public key. You then publish the public key so that anyone can check that the signature is valid, and since the public key is related to the private key, it gives you assurance of who created that signature. Furthermore, you can verify that the commit hasn't been tampered with, because a tampered commit will also make the signature fail verification,since the signature is based on the original data.

To complete the example above, Github knows who it can trust by you giving them your public key. That way, when you sign a commit, they can verify the signature, and only commits from its matching private key will show as "verified". So in all, if you can trust the person who signed a commit, you can also trust that they are the only one who created the commit.