Public-Private Key Cryptography Re-examined
Let’s do a free form thought experiment to learn about some central software security concepts.
- What “proving possession” is and how to prove it. I.e. how do you know you are talking to who you think you are talking to?
- What is a “challenge”?
- What “signing” is, how to sign something, and how to verify that someone specific signed something.
- What TLS is and how it works (including mutual TLS).
- What a certificate authority (CA) is. How to verify certificates with a CA.
- What HTTPS is and how it works.
Public-Private Key Pair
Let’s start with an axiom: anything encrypted with a public key can only be decrypted with the corresponding private key, and vice versa. We won’t get into the math (because I don’t know it lmao).
Proving Possession
You (A) want to establish a communication channel with some entity B. How do you verify that it is really B that you are communicating with? You have B’s public key (you know who you want to communicate with), you issue “him” (person claiming to be B) a challenge, and he uses his private key to solve the challenge. Now you know it’s really B.
sequenceDiagram
participant A
participant B
A->>B: Challenge
B->>A: Response
Note right of B: B used his private key to solve the challenge
A->>A: Verify
Note right of A: A verifies the challenge was correctly solved
Essentially, someone can prove they are B by knowing something only B would know (his private key). The challenge is to prove he has the private key.
Let’s dive in a little. There are two main ways to do this challenge. Let me explain via diagrams. Less words more diagrams :).
sequenceDiagram
participant A
participant B
A->>B: Challenge
Note right of B: A's challenge is a random string encrypted with B's public key
B->>A: Response
Note right of B: B decrypts it with his private key, returns the original random string
A->>A: Verify
Note right of A: A verifies he got back the same random string he sent
By the way, this whole thing is called “proving possession”. This is how you can prove that someone possesses the private key corresponding to a public key.
Here’s a second way to do a challenge.
sequenceDiagram
participant A
participant B
A->>B: Challenge
Note right of B: A generates a random string, Asks B to sign it with his private key
B->>A: Response
Note right of B: B signs the random string with his private key
A->>A: Verify
Note right of A: A decrypts the signature using B's public key, sees if original string is there
So, you start with a random string S, B encrypts (transforms) it with his private key into S’. You transform S’ using B’s public key and you get back S, thus possession is proven.
graph LR
S -->|transform with B's private key| S'
S' -->|transform with B's public key| S
Signing
When you want to sign a message, you create a hash of the message and then encrypt the hash with your private key. This (the encrypted hash) is called the signature of the message (it is included with the message).
When someone wants to verify that it was you (A) who signed it. They will take your public key and decrypt the signature. If the decrypted hash matches the hash of the message, then it was indeed you who signed it.
graph TD
Hash -->|transform with private key| Signature
Signature -->|transform with public key| Hash'
Hash' --> C{Same as original hash?}
C -->|yes| Verified
C -->|no| NotVerified
Signing a message is done with a private key. Verification is done with a public key.
TLS
TLS is when you want to establish a secure communication channel over an insecure network.
Goes back to what we started with. If you are A and you want to talk to B. You need to verify that it is really B you are talking to (“proving possession” via a challenge).
Once you have verified B’s identity, you need to establish a secure communication channel. You do this by agreeing on a symmetric key (a key that both A and B know). This symmetric key is then used to encrypt all communication between A and B.
A symmetric key is a key that can be used to both encrypt and decrypt a message.
The actual technology of the channel can be anything, though often it is a TCP connection.
Certificates and Certificate Authorities
One caveat - in TLS, the server presents a “certificate” to the client. This certificate contains the server’s public key (as well as some “claims”/”roles”). This certificate is signed by a 3rd party, called a certificate authority (CA).
You 1) verify validity of the certificate (check if it’s signed by a trusted CA) 2) verify that server identity is who is stated on the cert (the public key stated in the cert). 1 is done by verifying the signature on the certificate presented (that it is the signiture of the CA). 2 is done by a challenge.
The purpose of the certificate is to bind the public key to certain things like the identity, permissions, and other attributes of the entity it represents.
Mutual TLS
In non mutual TLS, only one entity (generally called the “server”) is authenticated (proves identity, proves possession). In mutual TLS, both entities (the “client” and the “server”) authenticate each other.
You can imagine how this works. Both have certificates issues by a CA. Both exchange certificates with one another. Both verify the other’s certificate using the CA.
Verifying a certificate means checking that it was signed by a CA.
HTTPS
HTTPS is simply HTTP over a TLS (TCP) socket. That’s it! Short and sweet :).
This is the benefit of learning fundamentals well, higher level concepts barely add anything new!