ЁЯПл The SchoolтА║ЁЯХ╕я╕П NetworkingтА║ЁЯФТ рдзрдбрд╛ 08 тАФ TLS рдЖрдгрд┐ certificates: рд╕реАрд▓ рдХреЗрд▓реЗрд▓рд╛ рд▓рдЦреЛрдЯрд╛
ЁЯЦ╝я╕П See the drawing + lab ЁЯПа Course home ЁЯМ┐ Branch on GitHub тЬПя╕П View source
ЁЯЦ╝я╕П рдЖрдХреГрддреА рдЖрдгрд┐ labThe drawing + lab рдкреВрд░реНрдг рдкрд╛рдирд╛рд╡рд░ рдЙрдШрдбрд╛ тЖЧOpen full page тЖЧ

ЁЯФТ рдзрдбрд╛ 08 тАФ TLS рдЖрдгрд┐ certificates: рд╕реАрд▓ рдХреЗрд▓реЗрд▓рд╛ рд▓рдЦреЛрдЯрд╛

ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 08 ┬╖ рдкреБрдвреЗ: lesson-09-routing


ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ

рдзрдбреЗ 01тАУ08. Certificates, рддреНрдпрд╛рдВрдЪреНрдпрд╛рд╡рд░ рд╕рд╣реА рдХрд░рдгрд╛рд░реА authority, handshake, рдЖрдгрд┐ Python рдордзреНрдпреЗ рдЦрд░реЗ certificate рд╡рд╛рдЪрдгреЗ.

ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ

рд╕рд╛рдзрд╛ рд▓рдЦреЛрдЯрд╛ corridor рдордзрд▓рд╛ рдХреЛрдгреАрд╣реА рдЙрдШрдбреВ рд╢рдХрддреЛ. рд╕реАрд▓ рдХреЗрд▓реЗрд▓рд╛ рд▓рдЦреЛрдЯрд╛ рдЙрдШрдбрддрд╛ рдпреЗрдд рдирд╛рд╣реА тАФ рдкрдг рд╕реАрд▓ рдХреЛрдгрд╛рдЪреЗ рдЖрд╣реЗ рд╣реЗ рдорд╛рд╣реАрдд рдЕрд╕реЗрд▓ рддрд░рдЪ рддреНрдпрд╛рдЪрд╛ рдЙрдкрдпреЛрдЧ. рдореНрд╣рдгреВрди server рдПрдХ рдУрд│рдЦрдкрддреНрд░ (certificate) рджрд╛рдЦрд╡рддреЛ: "рдореА example.com рдЖрд╣реЗ", рдЬреНрдпрд╛рд╡рд░ рд╕рдЧрд│реНрдпрд╛рдВрдЪрд╛ рд╡рд┐рд╢реНрд╡рд╛рд╕ рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рдореБрдЦреНрдп рдХрд╛рд░реНрдпрд╛рд▓рдпрд╛рдЪреА (certificate authority) рд╕рд╣реА рдЕрд╕рддреЗ. рддреБрдордЪрд╛ browser рд╕рд╣реА рдЖрдгрд┐ рдирд╛рд╡ рддрдкрд╛рд╕рддреЛ, рдордЧ рддреБрдореНрд╣реА рджреЛрдШреЗ рдпрд╛рдкреБрдврдЪрд╛ рдкреНрд░рддреНрдпреЗрдХ рд▓рдЦреЛрдЯрд╛ рд╕реАрд▓ рдХрд░рдгреНрдпрд╛рдЪреА рдПрдХ рдЧреБрдкреНрдд рдкрджреНрдзрдд рдард░рд╡рддрд╛. рд╣реЗрдЪ TLS рдЖрд╣реЗ; HTTPS рдореНрд╣рдгрдЬреЗ рддреНрдпрд╛рдЪреНрдпрд╛ рдЖрддрд▓реЗ HTTP.

ЁЯЧ║я╕П рдЖрдХреГрддреА

sequenceDiagram
  participant B as browser
  participant S as example.com :443
  B->>S: ClientHello (SNI: example.com, ciphers I speak)
  S->>B: ServerHello + certificate (signed by a CA) + key share
  B->>B: verify chain ┬╖ check name ┬╖ check dates
  B->>S: Finished тАФ session keys agreed
  Note over B,S: everything after is encrypted and tamper-proof

тЭУ рдХрд╛рдп

ЁЯдФ рдХрд╛

рдХреЛрдгреАрд╣реА рди рдЖрдЦрд▓реЗрд▓реНрдпрд╛ outages рдЪреНрдпрд╛ рдкрд╣рд┐рд▓реНрдпрд╛ рддреАрди рдХрд╛рд░рдгрд╛рдВрдкреИрдХреА рдПрдХ рдореНрд╣рдгрдЬреЗ expire рдЭрд╛рд▓реЗрд▓реЗ certificates. рдЪреБрдХреАрдЪреА рдирд╛рд╡реЗ, рдЧрд╣рд╛рд│ intermediates рдЖрдгрд┐ production рдордзрд▓реЗ self-signed certificates рд╣реА рдмрд╛рдХреАрдЪреА. рдПрдХрджрд╛ рдХреЗрд▓реЗ рдХреА certificate рд╡рд╛рдЪрд╛рдпрд▓рд╛ рджрд╣рд╛ seconds рд▓рд╛рдЧрддрд╛рдд.

ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)

tls() рдПрдХ TCP socket ssl.create_default_context() рдиреЗ рдЧреБрдВрдбрд╛рд│рддреЛ (рдЬреЛ рд╡рд┐рд╢реНрд╡рд╛рд╕реВ CAs load рдХрд░рддреЛ рдЖрдгрд┐ рдирд╛рд╡ рддрдкрд╛рд╕рддреЛ), рдордЧ version(), cipher(), рдЖрдгрд┐ getpeercert() рдордзрд▓реА fields рдЫрд╛рдкрддреЛ.

ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛

python3 net/demo.py tls
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | grep -E 'subject=|issuer=|Verify'
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates
curl -sv https://expired.badssl.com 2>&1 | grep -iE 'expired|SSL certificate' | head -2     # what a broken seal looks like

тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ

protocol TLSv1.3 (рдХрд┐рдВрд╡рд╛ 1.2), issuer рд╕рдВрд╕реНрдерд╛, рднрд╡рд┐рд╖реНрдпрд╛рддрд▓реА valid until рддрд╛рд░реАрдЦ, рдЖрдгрд┐ also valid for: ['example.com', '*.example.com']. badssl рдЪреА рддрдкрд╛рд╕рдгреА expiry error рджреЗрдКрди fail рд╣реЛрддреЗ тАФ рдореБрджреНрджрд╛рдо.

ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ

рдПрдЦрд╛рджреНрдпрд╛ site рдЪреА рд╣рдореА рдХреЛрдг рджреЗрддреЛ рдЖрдгрд┐ рдХрдзреАрдкрд░реНрдпрдВрдд рд╣реЗ рддреБрдореНрд╣реА рд╡рд╛рдЪреВ рд╢рдХрддрд╛ тАФ рдЖрдгрд┐ рд╕реАрд▓ рддреБрдЯрдгреНрдпрд╛рдЪреЗ рддреАрди рдкреНрд░рдХрд╛рд░ рдУрд│рдЦреВ рд╢рдХрддрд╛.

тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛

ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: certificate expiry monitoring, load balancers рд╡рд░рдЪреЗ SNI, services рдордзрд▓реЗ mTLS (API рд╢рд╛рд│рд╛ рдзрдбрд╛ 14) рдЖрдгрд┐ рд╕реНрд╡рд╛рдЧрдд рдХрдХреНрд╖рд╛рд╡рд░ рд╣реЛрдгрд╛рд░реЗ TLS termination (рдзрдбрд╛ 11) тАФ рд╣реЗ рд╕рдЧрд│реЗ рдореЛрдареНрдпрд╛ рдкреНрд░рдорд╛рдгрд╛рд╡рд░рдЪрд╛ рд╣рд╛рдЪ handshake рдЖрд╣реЗрдд.

тПня╕П рдкреБрдвреЗ

рдзрдбрд╛ 09 тАФ routing рдЖрдгрд┐ internet: рдХреЛрдгрд╛рдХрдбреЗрдЪ рдкреВрд░реНрдг рдирдХрд╛рд╢рд╛ рдирд╕рд▓реЗрд▓реА рдЗрдорд╛рд░рдд рдкрд┐рд╢рд╡реА рдХрд╢реА рд╢реЛрдзрддреЗ.

ЁЯФТ Lesson 08 тАФ TLS & certificates: the sealed envelope

ЁЯУН You are here: Lesson 08 of 12 ┬╖ Next: lesson-09-routing


ЁЯУж What's in this branch

Lessons 01тАУ08. Certificates, the authority that signs them, the handshake, and the reading of a real certificate in Python.

ЁЯзТ Explain like I'm 5

A plain envelope can be opened by anyone on the corridor. A sealed envelope cannot тАФ but a seal only helps if you know whose seal it is. So the server shows an ID card (the certificate): "I am example.com", signed by a head office everyone trusts (a certificate authority). Your browser checks the signature and the name, then the two of you agree a secret way to seal every envelope from now on. That is TLS; HTTPS is HTTP inside it.

ЁЯЧ║я╕П Diagram

sequenceDiagram
  participant B as browser
  participant S as example.com :443
  B->>S: ClientHello (SNI: example.com, ciphers I speak)
  S->>B: ServerHello + certificate (signed by a CA) + key share
  B->>B: verify chain ┬╖ check name ┬╖ check dates
  B->>S: Finished тАФ session keys agreed
  Note over B,S: everything after is encrypted and tamper-proof

тЭУ What

ЁЯдФ Why

Expired certificates are a top-three cause of outages nobody planned. Wrong names, missing intermediates and self-signed certificates in production are the others. Reading a certificate takes ten seconds once you have done it.

ЁЯФз How (in this repo)

tls() wraps a TCP socket with ssl.create_default_context() (which loads the trusted CAs and verifies the name), then prints version(), cipher(), and fields from getpeercert().

ЁЯзк Try it

python3 net/demo.py tls
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | grep -E 'subject=|issuer=|Verify'
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates
curl -sv https://expired.badssl.com 2>&1 | grep -iE 'expired|SSL certificate' | head -2     # what a broken seal looks like

тЬЕ Verify тАФ what you should see

protocol TLSv1.3 (or 1.2), an issuer organisation, a valid until date in the future, and also valid for: ['example.com', '*.example.com']. The badssl check fails with an expiry error тАФ on purpose.

ЁЯПБ What you just proved

You can read who vouches for a site and until when тАФ and recognise the three ways a seal breaks.

тЪая╕П Common mistakes

ЁЯПн Why this matters in production: certificate expiry monitoring, SNI on load balancers, mTLS between services (API school lesson 14) and TLS termination at the reception desk (lesson 11) are this handshake at scale.

тПня╕П Next

Lesson 09 тАФ routing & the internet: how a bag finds a building nobody has a full map to.

тЖР Previoushttp on the wireNext тЖТrouting

This page is the lesson's README from the lesson-08-tls branch, shown here so the whole School stays on one site. Code files open on GitHub at the same branch.