EXERCISE 2 — Creating and inspecting a self-signed certificate =============================================================== Generate a key + self-signed cert in one command: openssl req -x509 -newkey rsa:2048 -nodes \ -keyout selfsigned.key -out selfsigned.crt \ -days 365 -subj "/CN=localhost" -x509 = output a self-signed cert (not a CSR) -newkey rsa:2048 = make a fresh 2048-bit key at the same time -nodes = don't encrypt the private key (no passphrase prompt) -subj = supply the identity non-interactively Inspect it: openssl x509 -in selfsigned.crt -noout -subject -issuer subject=CN=localhost issuer=CN=localhost <-- Subject == Issuer CONFIRMING IT'S SELF-SIGNED: - Subject EQUALS Issuer: the cert names itself as its own issuer. It was signed with its OWN private key. There is no chain to anyone else. - That's structurally identical to a ROOT CA cert (roots are self-signed too) — the ONLY difference is that real roots are in the trust store and yours is not. WHY THE BROWSER REFUSES TO TRUST IT (even though traffic IS encrypted): - The TLS handshake will still negotiate keys and encrypt data — so you get CONFIDENTIALITY and INTEGRITY fine. - But AUTHENTICATION fails: the browser tries to walk the chain to a root in its trust store. A self-signed cert's chain terminates at ITSELF, and "itself" is not in the trust store -> no trusted anchor -> warning (e.g. NET::ERR_CERT_AUTHORITY_INVALID / "self-signed certificate"). - In other words: anyone can self-sign a cert claiming any name, so the signature proves nothing about identity. Encryption with an unverified party is the Chapter 1 problem — a private channel to a possible impostor. LEGITIMATE USES: - Local development (https://localhost), internal test servers, or cases where you control both ends and can manually trust the cert. - NEVER for the public web — visitors have no reason to trust it.