After running openssl req, there are two files: garagedoor.key and garagedoor.cert. Which goes where, and what happens if each one leaks?
The certificate goes to every client and may be public. The private key stays on the server only. A leaked certificate is harmless; a leaked key lets an attacker impersonate the server to every client that trusts that certificate.
| File | Contains | Goes to | If it leaks |
|---|---|---|---|
garagedoor.cert |
Public key, subject name, validity, self-signature | NodeJS server (to send in the handshake), ESP32 firmware, curl --cacert |
Nothing. The server sends it to every client anyway |
garagedoor.key |
Private key | NodeJS server only | Attacker can pose as the server: run a fake server, or sit in the middle and decrypt and relay traffic |
The asymmetry is the whole point of public-key cryptography. During the handshake the server proves it holds the private key (by signing its key-exchange values or decrypting the client's secret). The certificate tells the client which public key to check that proof against. Copying the certificate gives an attacker the lock, not the key.
What a leaked key does not expose. The demo connection used an ECDHE cipher suite, whose session keys come from temporary Diffie-Hellman values that are thrown away after each handshake. So a stolen server key does not decrypt past recordings, only lets the thief impersonate the server from now on. With the older RSA key exchange it would decrypt every session ever recorded.
Recovery from a leak is expensive with a pinned certificate: generate a new key and certificate, then rebuild and reflash every device, because each one has the old certificate compiled in.
Go deeper:
Wikipedia — Public-key cryptography — why the public half can be shared freely while the private half proves identity.
Wikipedia — Forward secrecy — why a later key compromise does not reveal earlier sessions.