You now have the four primitives: symmetric encryption, asymmetric encryption, hash with MAC, and digital signature. The previous lesson closed by announcing something uncomfortable, and this one develops it: combining correct primitives does not guarantee a secure system. The assembly — the order of the messages, what is authenticated, what is negotiated, what happens when something fails — has failure modes of its own, and the history of applied cryptography is full of protocols built with impeccable AES and impeccable RSA that broke because of how they were put together. This lesson studies the TLS you have been taking for granted for eight lessons — keeping module 2's promise — with its handshake step by step, how to verify it and how to configure it; and it adds SSH, VPN, mTLS, encrypted e-mail and the classic attacks against protocols: downgrade, stripping, MITM and replay.

Contents

  1. What a cryptographic protocol is and why it can fail
  2. TLS: what it protects and what it does not
  3. From SSL to TLS 1.3: what each version improves
  4. The TLS 1.3 handshake step by step
  5. Cipher suites: how to read them
  6. Verifying TLS from the command line
  7. Secure configuration of the Nimbus server
  8. mTLS: mutual TLS and when it makes sense
  9. Other protocols: SSH, VPN, e-mail and end-to-end encryption
  10. Attacks against protocols and their defences
  11. Implementation errors with real impact

  1. What a cryptographic protocol is and why it can fail

A cryptographic protocol is an agreed sequence of messages between two or more parties which, using cryptographic primitives, achieves a specific security goal: establishing a confidential channel, authenticating somebody, agreeing a key, proving possession of something.

The difference from a primitive is the same as the difference between a brick and a building. A brick is tested in a laboratory and holds; a building falls down because of the design, not because of the brick. The typical failure modes of a protocol are these, and none of them involves breaking the algebra:

Failure mode What it consists of Example
Not authenticating the exchange A key is agreed, but with the wrong party Diffie-Hellman without a certificate → MITM (03-03)
Manipulable negotiation The attacker forces the weakest option Downgrade attacks (section 10)
Lack of freshness An old but valid message is replayed Replaying the webhook with no timestamp (03-04)
Leaking information in the errors The response distinguishes between kinds of failure Padding oracle (03-02)
Getting the order of operations wrong Authentication and encryption badly combined MAC-then-encrypt versus AEAD
Unforeseen states Messages out of sequence or repeated State machine failures in TLS implementations

Hence the rule of this section, consistent with the whole module: protocols are not designed or implemented by hand either. You use standard protocols, with mature, up-to-date and well-configured implementations. Your professional job is to choose the right version, configure it properly and verify that it really does what you think it does.


  1. TLS: what it protects and what it does not

TLS (Transport Layer Security) is the protocol that turns HTTP into HTTPS, and it also protects SMTP, IMAP, database connections and practically anything that travels over a network today. It is the perfect example of hybrid encryption (03-03) taken into production.

TLS does protect TLS does not protect
Confidentiality of the content in transit The data once it arrives at the server
Integrity: it detects modification along the way Against a compromised or malicious server
Authenticity of the server through its certificate The domain name you connect to (it travels visibly in the DNS and, except with ECH, in the SNI)
Forward secrecy with ECDHE Metadata: who talks to whom, when and how much
Confidentiality against the intermediate network Against a compromised client (a phone with malware)

Two practical consequences worth saying out loud:

  • "It goes over HTTPS" does not mean "it is secure". The IDOR of 01-01, the SQL injection of 02-02 and the bucket leak of 02-06 would happen just the same over impeccable TLS. TLS protects the leg of the journey, not the application.
  • The browser padlock does not vouch for honesty. It vouches that you are talking to the domain shown in the bar. A phishing site with the domain nimbus-reservas-clientes.example will have its perfect padlock (02-03).

  1. From SSL to TLS 1.3: what each version improves

Version Year Status in 2026 Note
SSL 2.0 / 3.0 1995/1996 Forbidden Broken (POODLE and others)
TLS 1.0 1999 Obsolete Withdrawn by the browsers and by PCI DSS
TLS 1.1 2006 Obsolete Withdrawn along with 1.0
TLS 1.2 2008 Acceptable if the suites are restricted Still necessary for old clients
TLS 1.3 2018 Recommended What Nimbus should use by default

What TLS 1.3 improves, which is what you need to be able to explain:

  1. Fewer round trips. The handshake completes in 1-RTT (one round trip) against two in TLS 1.2. It shows in latency, especially from a phone.
  2. Reduced suites with no broken pieces. RC4, 3DES, MD5, SHA-1, compression, renegotiation and CBC modes with MAC-then-encrypt were removed from the standard. Only AEAD suites remain (03-02).
  3. Mandatory forward secrecy. Static RSA key exchange disappears: everything is ECDHE (03-03). You can no longer configure it badly, because the bad option does not exist.
  4. More of the handshake is encrypted, including the server certificate, which reduces what an observer learns.
  5. Less room for configuration errors. It is the most underrated improvement: TLS 1.3 is secure by default, whereas TLS 1.2 requires the administrator to get the suite list right.

There is a nuance worth knowing about: TLS 1.3 allows 0-RTT resumption, which sends data in the first message. It is fast, but that data is susceptible to replay, so it should only be used for idempotent requests. For the Nimbus API, the recommendation is not to enable 0-RTT.


  1. The TLS 1.3 handshake step by step

sequenceDiagram
    participant C as Client (mobile app)
    participant S as Server (Nimbus API)
    C->>S: ClientHello<br/>versions, AEAD suites,<br/>ephemeral public key (ECDHE),<br/>SNI = api.nimbusreservas.example
    S->>S: Generates its ephemeral pair<br/>and computes the shared secret
    S->>C: ServerHello<br/>chosen suite + ephemeral public key
    Note over C,S: From here on EVERYTHING is encrypted
    S->>C: {Certificate + chain}<br/>{CertificateVerify: signature with the private key}<br/>{Finished}
    C->>C: Validates the chain, the name,<br/>the validity period and the signature
    C->>S: {Finished}
    Note over C,S: Channel established: AES-GCM or ChaCha20-Poly1305

The five moments, with what each one contributes:

  1. ClientHello. The client proposes versions and suites and — the key to 1-RTT — already sends its ephemeral public key, bringing the ECDHE exchange forward. It includes the SNI, the name of the server it wants to connect to, necessary because a single IP hosts many domains.
  2. ServerHello. The server chooses the suite and sends its ephemeral public key. With the two halves, both compute the same shared secret (03-03) and derive the session keys from it using HKDF (03-02). This is where ECDHE comes in and where forward secrecy is born.
  3. From this point everything is encrypted, including the certificate.
  4. Certificate and CertificateVerify. The server sends its certificate and its chain, and signs a digest of the whole handshake with its private key. This is what authenticates the exchange and closes the door on the MITM of 03-03: the attacker can do their own ECDHE, but they cannot produce that signature without the private key corresponding to the certificate. The client validates the chain up to a trusted root, the domain name, the validity period and the signature — what is issued and how it is validated is the subject of 03-06.
  5. Finished in both directions. Each end proves that it has seen exactly the same messages. This is what detects a downgrade: if an attacker had altered the ClientHello to force a weak suite, the digest would not match.

From then on, the traffic is encrypted with AES-GCM or ChaCha20-Poly1305 and symmetric keys. It is exactly the hybrid pattern of 03-03: asymmetric cryptography only to agree and authenticate, symmetric cryptography for the data.


  1. Cipher suites: how to read them

A cipher suite is the specific combination of algorithms used in a session. In TLS 1.2 the name includes four pieces:

TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
    |     |         |            |
    |     |         |            +-- hash function for derivation and MAC
    |     |         +-- encryption of the data: AES-256 in GCM mode (AEAD)
    |     +-- server authentication: RSA signature (from the certificate)
    +-- key exchange: ECDHE (ephemeral -> forward secrecy)

In TLS 1.3 the names are much shorter, because the exchange and the authentication are no longer negotiated in the suite:

TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256
TLS_AES_128_GCM_SHA256

How to evaluate a suite at a glance: if the exchange does not start with ECDHE (or DHE), there is no forward secrecy; if the encryption is CBC, RC4 or 3DES, it is out; if the hash is MD5 or SHA (meaning SHA-1), it is out. The three TLS 1.3 suites are all correct, which is precisely the advantage of that version.


  1. Verifying TLS from the command line

Being able to read the real state of a server is a basic operational skill. Lucía checks the Nimbus API:

# Full connection: shows certificate, chain, version and suite
openssl s_client -connect api.nimbusreservas.example:443 \
  -servername api.nimbusreservas.example </dev/null 2>/dev/null | head -40

# Check whether the server ACCEPTS an obsolete version (it must FAIL)
openssl s_client -connect api.nimbusreservas.example:443 -tls1_1 </dev/null

# Show only the certificate validity dates
echo | openssl s_client -connect api.nimbusreservas.example:443 \
  -servername api.nimbusreservas.example 2>/dev/null \
  | openssl x509 -noout -dates -subject -issuer

Annotated output of the first command:

CONNECTED(00000003)
depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = R11
verify return:1
depth=0 CN = api.nimbusreservas.example
verify return:1
---
Certificate chain
 0 s:CN = api.nimbusreservas.example
   i:C = US, O = Let's Encrypt, CN = R11
 1 s:C = US, O = Let's Encrypt, CN = R11
   i:C = US, O = Internet Security Research Group, CN = ISRG Root X1
---
SSL handshake has read 4521 bytes and written 396 bytes
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 256 bit
Verify return code: 0 (ok)

How to read this output, which is the important part:

  • depth=2, depth=1, depth=0 are the three links in the chain: root, intermediate and the server certificate. verify return:1 on each one means that link validated.
  • Certificate chain shows, for each certificate, its subject (s:) and its issuer (i:). Note the chaining: the issuer of one is the subject of the next. The complete hierarchy is the subject of 03-06.
  • New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384 is the line that summarises the outcome: negotiated version and suite. If TLSv1.0 or a suite with CBC appeared here, there would be a finding.
  • Server public key is 256 bit indicates a 256-bit ECC key (equivalent to RSA-3072, table in 03-03). If it said 2048, it would be RSA.
  • Verify return code: 0 (ok) is the complete validation. Any other value — 10 expired, 18 self-signed, 19 untrusted root, 21 could not be verified — is a problem.
  • The options: -servername sends the SNI, indispensable when the IP hosts several domains; without it you may be looking at a certificate that is not yours. </dev/null closes the input so that the command does not sit there waiting.

And the HSTS check, which is done on the HTTP headers:

curl -sI https://api.nimbusreservas.example | grep -i "strict-transport\|^HTTP"
HTTP/2 200
strict-transport-security: max-age=63072000; includeSubDomains; preload

  1. Secure configuration of the Nimbus server

An extract of the Nginx configuration for the Nimbus front end, explained directive by directive:

server {
    listen 443 ssl;
    http2 on;
    server_name api.nimbusreservas.example;

    ssl_certificate     /etc/letsencrypt/live/nimbus/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/nimbus/privkey.pem;

    # 1. Current versions only
    ssl_protocols TLSv1.2 TLSv1.3;

    # 2. Suites allowed in TLS 1.2 (in 1.3 the protocol itself fixes them)
    ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
    ssl_prefer_server_ciphers off;

    # 3. Curves for the ephemeral exchange
    ssl_ecdh_curve X25519:prime256v1;

    # 4. Session resumption, without 0-RTT
    ssl_session_cache shared:TLS:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;
    ssl_early_data off;

    # 5. OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 1.1.1.1 9.9.9.9 valid=300s;

    # 6. HSTS
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
}

# 7. Permanent redirect from HTTP to HTTPS
server {
    listen 80;
    server_name api.nimbusreservas.example;
    return 301 https://$host$request_uri;
}

What each block does:

  1. ssl_protocols TLSv1.2 TLSv1.3. It disables SSL and TLS 1.0/1.1. If your whole client base is modern, leaving only TLSv1.3 is better still; measure it first against the access logs.
  2. ssl_ciphers. Only ECDHE suites (forward secrecy) with AEAD. ssl_prefer_server_ciphers off is what is recommended today: the client is allowed to choose within the permitted list, because a phone without AES acceleration will choose ChaCha20 and will be faster with the same security.
  3. ssl_ecdh_curve X25519:prime256v1. It prioritises X25519 (03-03), faster and harder to implement badly.
  4. Resumption. The cache speeds up reconnections. ssl_session_tickets off avoids the risk of a badly rotated ticket key cancelling forward secrecy; ssl_early_data off disables 0-RTT because of the replay risk.
  5. OCSP stapling. The server attaches to the handshake a recent proof that its certificate has not been revoked, instead of forcing the client to look it up. It improves privacy and latency; the revocation mechanism is studied in 03-06.
  6. HSTS. max-age=63072000 (two years) tells the browser to use only HTTPS for this domain; includeSubDomains extends it to every subdomain and preload allows it to be included in the browsers' preloaded list. It is the defence against the stripping of section 10. Careful: includeSubDomains and preload are hard to reverse; check first that all the subdomains serve HTTPS.
  7. 301 redirect from HTTP to HTTPS. Necessary, but not sufficient: the first request still travels in the clear. That is why HSTS is needed.

Always verify the result with an external TLS configuration analyser and with the commands from section 6: the written configuration and the effective one do not always coincide, especially with load balancers or a CDN in front.


  1. mTLS: mutual TLS and when it makes sense

In ordinary TLS only the server is authenticated; the client identifies itself afterwards, inside the channel, with a password or a token. In mTLS (mutual TLS), both ends present a certificate and both are authenticated during the handshake itself.

Scenario in Nimbus mTLS? Reason
Mobile app and SPA of end customers No Thousands of devices: distributing and rotating certificates is unfeasible. Use OIDC and tokens (02-05)
Communication with the payment gateway Yes, if the provider offers it Few endpoints, high value, a common requirement in the sector
Between internal services (API ↔ background workers) Yes, recommended It puts the Zero Trust of 01-03 into practice: each service proves its identity on every connection
Consultancy access (A-19) Advisable, together with MFA and just-in-time access It reinforces control of the third party that caused the incident of 02-06

What it contributes: authentication happens before the application processes anything, so an attacker without a valid certificate does not even reach the business logic. What it costs: you have to issue, distribute, renew and revoke a certificate per client, which requires an internal PKI — the subject of 03-06. The practical rule: mTLS between a few high-value systems, tokens for many users.


  1. Other protocols: SSH, VPN, e-mail and end-to-end encryption

Protocol What it guarantees Use in Nimbus
SSH An encrypted, authenticated channel for remote administration Lucía's access to the servers
IPsec Network-level encryption, standard and mature, complex configuration Site-to-site VPN
WireGuard Modern encryption, small code base, very fast, no options to get wrong Remote access VPN
S/MIME E-mail signing and encryption with certificates from a CA Corporate e-mail with formal requirements
PGP/GPG Signing and encryption of e-mail and files, with a web of trust Occasional exchanges; usable but awkward
Signal Protocol End-to-end encryption with per-message forward secrecy Messaging; the reference concept for E2EE
RFC 3161 (timestamping) Proof that a piece of data existed on a given date Timestamping audit logs

SSH deserves some detail, because its trust model is different from that of TLS: there are no certificate authorities, but a host fingerprint that the client memorises the first time (trust on first use).

# Generate an Ed25519 key for Lucia (03-03)
ssh-keygen -t ed25519 -C "lucia@nimbusreservas.example" -f ~/.ssh/id_ed25519_nimbus

# Show the fingerprint of the public key
ssh-keygen -lf ~/.ssh/id_ed25519_nimbus.pub

# Obtain the server fingerprint BEFORE connecting for the first time,
# over a different channel (provider console, internal documentation)
ssh-keyscan -t ed25519 bastion.nimbusreservas.example | ssh-keygen -lf -
256 SHA256:aQ2vR7xK0mN3pLdT9wYcF1uZgB8sEjH5rXo4VnQiM2k lucia@nimbusreservas.example (ED25519)
256 SHA256:7fJkP0sWqL9mR2xN4dV6yTgB1cZuH8eA3oXiK5vQnE0 bastion.nimbusreservas.example (ED25519)

The essential point: when SSH warns that the host key has changed or is unknown, accepting blindly amounts to accepting a possible MITM. The fingerprint must be compared with one obtained over another channel. And for an estate like Nimbus's, the solution that scales is to sign the host keys with an SSH CA, which replaces memorisation with hierarchical trust (03-06). Also: key-only authentication — PasswordAuthentication no — a key protected with a passphrase and no direct root access; the full hardening of the server belongs to 05-06.

On VPNs, all that matters here is what they guarantee: an encrypted, authenticated tunnel between two points. They do not provide access control to the applications, nor do they make whatever is inside trustworthy. The network deployment is covered in 05-04.

And end-to-end encryption as a concept: the data is encrypted on the sender's device and only decrypted on the recipient's, so that not even the service provider can read it. That is the difference from TLS, where the server does see the content. For Nimbus, full E2EE would be incompatible with its function — the application needs to process the appointments — but the concept reappears in 03-07 when we talk about field-level encryption.


  1. Attacks against protocols and their defences

Attack How it works Defence
Downgrade The negotiation is manipulated to force a weak version or suite Disable old versions; the TLS 1.3 Finished detects the manipulation
SSL stripping The attacker intercepts the initial HTTP request and serves everything over HTTP, without the user noticing HSTS (better with preload), 301 redirect, cookies with Secure
MITM with a false certificate The attacker presents a certificate of their own; it only works if the client does not validate or if a CA issued one improperly Strict validation, pinning, certificate transparency (03-06)
Replay A captured legitimate message is resent Nonces, timestamps, windows, counters, idempotency
Padding oracle Decryption by observing how the server responds to invalid padding AEAD; TLS 1.3 eliminates it by design
Compression (CRIME/BREACH) The compressed size leaks information about the secret No TLS compression; be careful with application-level compression

Two deserve to be developed:

Stripping is the most profitable attack against a user on a public Wi-Fi network, and it does not break TLS: it sidesteps it. The victim types nimbusreservas.example without https://, the browser tries HTTP, and the attacker intercepts that initial request and acts as a cleartext proxy towards the user while talking HTTPS with the real server. HSTS cuts it off because the browser, after the first legitimate visit, refuses to use HTTP for that domain. And preload closes that first visit too, since the rule comes factory-fitted in the browser.

Pinning consists of the client demanding not just a valid certificate, but a specific one (or a specific CA). It works against the scenario of a CA issuing an improper certificate for your domain. It carries a serious risk: if the certificate is rotated without updating the pin, the application stops working and the only fix is to publish a new version. Recommendation for Nimbus: consider it in the mobile app — where the update cycle is controllable and the pin can point at the CA, not at the leaf — and not in the browser. For everything else, certificate transparency (03-06) covers the same risk at far lower operational cost.


  1. Implementation errors with real impact

The protocol can be impeccable and the implementation can cancel it out. The canonical example, already cited in 02-02:

# =============== WRONG — NEVER USE ===============
import requests

# "It was not working because of a certificate error and this way it does"
r = requests.get("https://api.pasarela-pago.example/v1/cobros",
                 verify=False)          # <-- DISABLES ALL VALIDATION
# =================================================

What that line means exactly: the connection is still encrypted, but any certificate is accepted, including an attacker's. In other words, the cost of TLS is kept and its guarantee is lost entirely, because without authenticating the other end the encryption protects a conversation with whoever happens to be there. It is the MITM of 03-03 served on a plate, and in this particular case it would expose the traffic with the payment gateway.

The correct version, with the three situations that usually prompt the shortcut:

import requests

# 1. NORMAL CASE: validation is enabled by default. Do not touch anything.
r = requests.get("https://api.pasarela-pago.example/v1/cobros",
                 timeout=10)

# 2. INTERNAL CA (internal Nimbus services with their own PKI, 03-06):
#    you point at the trusted root certificate, you do NOT disable validation.
r = requests.get("https://interno.nimbus.local/metricas",
                 verify="/etc/nimbus/ca-internal.pem", timeout=10)

# 3. mTLS (section 8): a client certificate as well as validating the server.
r = requests.get("https://api.pasarela-pago.example/v1/cobros",
                 cert=("/etc/nimbus/client.pem", "/etc/nimbus/client.key"),
                 timeout=10)

Other errors in the same family, all common and all equally serious:

Error Consequence
Validating the certificate signature but not the domain name Any valid certificate from any domain will do
Not checking the expiry or ignoring revocation A withdrawn certificate is accepted
Catching the validation exception and retrying without validation The failure turns into a silent vulnerability
Trusting a CA added to the system trust store for debugging and forgetting it A permanent back door
Putting verify=False only in development… and letting the code reach production It happens constantly

The organisational defence is the usual one: a check in CI (02-04) that rejects verify=False, InsecureSkipVerify, rejectUnauthorized: false and curl -k, and a mandatory two-person review for any justified exception, with an expiry date and an associated ticket.


Common Mistakes and Tips

Conceptual

  1. Believing that HTTPS makes the application secure. It protects the leg of the journey, not the logic.
  2. Taking the padlock as proof of honesty. It vouches for the domain, nothing more.
  3. Thinking that a VPN replaces access control. It gives a tunnel; inside the tunnel you still have to authorise.
  4. Assuming the certificate renews itself because "we set it up with Let's Encrypt". Automatic renewal breaks too, and it has to be monitored (03-06).

Configuration

  1. Leaving TLS 1.0/1.1 or suites with CBC, RC4 or 3DES enabled.
  2. Redirecting to HTTPS without HSTS. The first request still travels in the clear.
  3. Turning on includeSubDomains and preload without checking every subdomain. Hard to reverse; it can leave services unreachable.
  4. Enabling 0-RTT without analysing replay.
  5. Not verifying the effective configuration when there is a CDN or load balancer in front: what the front end serves may not be what you configured.

Implementation

  1. verify=False and its equivalents. The canonical error.
  2. Validating the chain but not the host name.
  3. Blindly accepting a new or changed SSH fingerprint.
  4. Setting a certificate pin with no rotation plan. It turns a routine renewal into an outage.

Tips

  • Configure TLS 1.3 by default, leave 1.2 only with ECDHE-AEAD suites if you have old clients, and review that decision with data from your logs every six months.
  • Monitor the expiry date of every certificate with alerts at 30 and 7 days. An expired certificate is an availability incident, and at Equifax (02-06) it also blinded detection.
  • Automate the verification: a scheduled check that runs openssl s_client against your domains and alerts if the version, the suite or the certificate fingerprint changes.
  • Remember the hierarchy of responsibility: the protocol is chosen by the standards, the version and the configuration are chosen by you, and the validation is respected by your code. All three have to be right.

Exercises

Exercise 1 — Reading a TLS diagnosis

Lucía runs openssl s_client against an internal service and gets:

depth=0 CN = interno.nimbus.local
verify error:num=18:self signed certificate
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-SHA384
Server public key is 2048 bit
Verify return code: 18 (self signed certificate)

You are asked to: (a) list all the problems this output reveals and rank them by severity; (b) explain which specific guarantee is lost with each one; (c) state whether a self-signed certificate is always a failure or can be acceptable, and under what conditions; (d) propose the target configuration for this internal service.

Exercise 2 — Designing the protection of the channel with the gateway

Nimbus is integrating a new payment gateway. The provider offers: TLS 1.2 or 1.3, optional mTLS, HMAC signing of the webhooks and an IP allowlist.

You are asked to: (a) decide which mechanisms to enable and in which direction each one acts (Nimbus→gateway, gateway→Nimbus); (b) explain which specific threat each mechanism stops and which ones overlap; (c) state what happens if the private key of Nimbus's client certificate leaks, and what must happen then; (d) reason whether the IP allowlist is a cryptographic control and what real value it adds.

Exercise 3 — Explaining HSTS and stripping

Rubén asks why, if the Nimbus website "redirects to HTTPS on its own", anything else needs configuring.

You are asked to: (a) describe step by step a stripping attack against a Nimbus customer on a café's Wi-Fi; (b) explain why the 301 redirect does not prevent it; (c) explain what HSTS does and what preload adds; (d) state the two operational risks of includeSubDomains and preload and how they are mitigated before turning them on.


Solutions

Exercise 1

(a) and (b) Problems by severity:

Severity Problem Guarantee lost
High Self-signed certificate (code 18): no trusted CA backs it Server authentication. Without it, the channel is encrypted with whoever happens to be there: MITM is possible
Medium Suite AES256-SHA384 without GCM: it is CBC with MAC-then-encrypt Robust integrity and resistance to padding oracles. It is not AEAD
Medium TLS 1.2 instead of 1.3 A handshake with more surface, configurable negotiation, more room for error
Low 2048-bit RSA key Nothing urgent (~112 bits), but below the recommendation of 128; migrate to ECC P-256 or RSA-3072

(c) Is it always a failure? Not necessarily. For an internal service, what is unacceptable is not that the certificate is not signed by a public CA, but that it is not signed by anything the client explicitly trusts. It is acceptable if there is an internal CA whose root certificate is installed on the clients and they genuinely validate against it (verify="/path/ca-internal.pem", section 11). What is never acceptable is the usual combination: a self-signed certificate plus verify=False in the clients, which is encryption without authentication.

(d) Target configuration: a certificate issued by Nimbus's internal CA (03-06), with the correct SAN for interno.nimbus.local; TLS 1.3 only, since all the clients are our own; an ECDSA P-256 or Ed25519 key; strict validation in every client against the internal root; and, given that this is service-to-service communication, mTLS (section 8), with automated renewal and an expiry alert.

Exercise 2

(a) and (b) Mechanisms:

Mechanism Direction Threat it stops
TLS 1.3 with strict validation Nimbus → gateway Interception and MITM of the payment traffic. Indispensable
mTLS Nimbus → gateway A third party with stolen credentials calling the gateway API on behalf of Nimbus. It adds authentication before the application
HMAC on the webhook Gateway → Nimbus Forged payment notifications from anybody who discovers the URL (03-04). Indispensable
IP allowlist Both It reduces the surface: only connections from known ranges are accepted

Overlaps. mTLS and the allowlist partially overlap in the Nimbus→gateway direction, but they act at different layers (cryptographic identity versus network origin) and are complementary in defence in depth (01-03). TLS and HMAC do not overlap: TLS protects the channel, HMAC protects the message, and HMAC is still needed even if the webhook arrives over HTTPS, because HTTPS vouches for the channel, not for who composed the content.

(c) If the private key of the client certificate leaks: an attacker could authenticate to the gateway as Nimbus. The certificate must be revoked immediately, a new one issued with a new key and deployed, the provider notified, the gateway logs reviewed for unrecognised operations, and the root cause analysis run (why was the key accessible). The complete life cycle is in 03-06.

(d) The IP allowlist is not a cryptographic control: it provides neither confidentiality, nor integrity, nor demonstrable authenticity, and the source address is spoofable in some scenarios. Its real value is to reduce the attack surface (01-04) and filter out automated noise. It is a useful and cheap control, but it can never replace TLS or the HMAC.

Exercise 3

(a) The attack, step by step. (1) The customer connects to the café's Wi-Fi, where the attacker controls the access point or is doing ARP poisoning. (2) They type nimbusreservas.example into the browser, without https://. (3) The browser issues a cleartext HTTP request. (4) The attacker intercepts it and does not let it through; instead they establish a legitimate HTTPS connection with Nimbus and serve the user the same content over HTTP. (5) The user sees the correct site, with no padlock — few people look — and enters their credentials. (6) The attacker reads them in the clear and forwards them to Nimbus, which sees a perfectly normal session.

(b) Why the 301 redirect is not enough. The redirect is sent by the server, and in this attack the initial request never reaches the server: the attacker intercepts it and simply does not redirect. The redirect only acts when the traffic reaches Nimbus; the attack lives precisely in the leg before that.

(c) What HSTS does. The Strict-Transport-Security header tells the browser that, for max-age seconds, it must use HTTPS for that domain, internally turning any http:// into https:// before anything is sent over the network. After a single legitimate visit, stripping stops working. preload goes further: the domain is entered in a list the browsers ship with, so the rule applies even on the first visit, covering the only gap that was left.

(d) The two operational risks. (1) includeSubDomains forces HTTPS on every subdomain, present and future; if any of them — an internal site, a test environment, an old admin panel — only serves HTTP, it will become unreachable from browsers that have seen the header. (2) preload is very hard to reverse: removal from the list takes months to propagate with the browser releases, so a mistake is dragged along for a long time. Mitigation: inventory every subdomain and check that they serve valid HTTPS; deploy first with a short max-age (300 seconds, for example) and without preload; verify for a few weeks; and only then raise it to two years and request inclusion.


Conclusion

You have made the jump from the pieces to the assembly, and with it an idea worth not forgetting: combining correct primitives is not enough, because a protocol fails by not authenticating the exchange, by a manipulable negotiation, by a lack of freshness, by leaking information in the errors or by unforeseen states — none of those failures requires breaking the algebra. Hence the natural extension of the module's rule: protocols are not designed by hand either; they are chosen, configured and verified.

And you have settled the debt outstanding since module 2. You know what TLS protects — confidentiality, integrity, server authenticity and forward secrecy on the leg of the journey — and what it does not: the application, the metadata, the compromised server and the infected client. You know the evolution up to TLS 1.3 and its five improvements, the most important being the one least often cited: that it is secure by default, because the bad options no longer exist. You have walked through the handshake step by step, seeing exactly where ECDHE comes in — and with it forward secrecy — where the certificate comes in with its CertificateVerify, which is what closes the door on the MITM, and where the symmetric AEAD encryption starts; you can read a suite and discard at a glance the ones without ECDHE or with CBC. You have verified it in practice with openssl s_client, interpreting depth, chain, version, suite and Verify return code, and with curl -I for HSTS; and you have configured the Nimbus front end directive by directive: versions, suites, curves, resumption without 0-RTT, OCSP stapling, HSTS and the redirect. You add mTLS for a few high-value systems, the overview of SSH with its trust on first connection and the fingerprint that is never accepted blindly, IPsec and WireGuard, S/MIME and PGP, E2EE as a concept and timestamping. You close with the classic attacks — downgrade, stripping with HSTS as the answer, MITM with a false certificate and the real role and risks of pinning, replay, the padding oracle and compression — and with the canonical implementation error, verify=False, which keeps the entire cost of TLS and cancels its guarantee completely.

But note how many times you have had to postpone the same answer. How does the client know that certificate belongs to Nimbus? Who issued it and with what guarantee? What happens when the key leaks or the certificate expires? How is the internal CA that mTLS and the internal services need actually set up? All the security in this chapter rests on the validation of a certificate, and we have not yet opened that box.

In Key Management, Certificates and PKI (03-06) we enter what module 2 announced as "the really hard problem", and the thesis is emphatic: algorithms almost never fail; key management does. You will see the complete life cycle of a key, where it must live — from the environment variable to the HSM — why deleting the commit with the leaked .env from the incident of 02-06 is not enough, how a key is rotated without interrupting the service, exactly what an X.509 certificate contains, how the chain of trust works, what CAs guarantee, how issuance works with ACME, how revocation works and how certificate transparency lets Nimbus detect a certificate improperly issued for its domain.

Fundamentals of Information Security Course

Module 1: Introduction to Information Security

Module 2: Cybersecurity

Module 3: Cryptography

Module 4: Risk Management and Protection Measures

Module 5: Security Tools and Techniques

Module 6: Best Practices and Regulations

Module 7: Final Project

© Copyright 2026. All rights reserved