ssl-talk/index.html

440 lines
16 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<title>SSL/TLS basics</title>
<meta charset="utf-8">
<style>
@import url(https://fonts.googleapis.com/css?family=Droid+Serif);
@import url(https://fonts.googleapis.com/css?family=Yanone+Kaffeesatz);
@import url(https://fonts.googleapis.com/css?family=Ubuntu+Mono:400,700,400italic);
body {
font-family: 'Droid Serif';
}
h1, h2, h3 {
font-family: 'Yanone Kaffeesatz';
font-weight: 400;
margin-bottom: 0;
}
.remark-slide-content h1 { font-size: 3em; }
.remark-slide-content h2 { font-size: 2em; }
.remark-slide-content h3 { font-size: 1.6em; }
.footnote {
position: absolute;
bottom: 3em;
font-size: 0.7em;
}
li p { line-height: 1.25em; }
.red { color: #fa0000; }
.large { font-size: 2em; }
a, a > code {
color: rgb(249, 38, 114);
text-decoration: none;
}
code {
background: #e7e8e2;
border-radius: 5px;
}
.remark-code, .remark-inline-code { font-family: 'Ubuntu Mono'; }
.remark-code-line-highlighted { background-color: #373832; }
.pull-left {
float: left;
width: 47%;
}
.pull-right {
float: right;
width: 47%;
}
.pull-right ~ p {
clear: both;
}
#slideshow .slide .content code {
font-size: 0.8em;
}
#slideshow .slide .content pre code {
font-size: 0.9em;
padding: 15px;
}
.inverse {
background: #272822;
color: #777872;
text-shadow: 0 0 20px #333;
}
.inverse h1, .inverse h2 {
color: #f3f3f3;
line-height: 0.8em;
}
/* Slide-specific styling */
#slide-inverse .footnote {
bottom: 12px;
left: 20px;
}
#slide-how .slides {
font-size: 0.9em;
position: absolute;
top: 151px;
right: 140px;
}
#slide-how .slides h3 {
margin-top: 0.2em;
}
#slide-how .slides .first, #slide-how .slides .second {
padding: 1px 20px;
height: 90px;
width: 120px;
-moz-box-shadow: 0 0 10px #777;
-webkit-box-shadow: 0 0 10px #777;
box-shadow: 0 0 10px #777;
}
#slide-how .slides .first {
background: #fff;
position: absolute;
top: 20%;
left: 20%;
z-index: 1;
}
#slide-how .slides .second {
position: relative;
background: #fff;
z-index: 0;
}
/* Two-column layout */
.left-column {
color: #777;
width: 20%;
height: 92%;
float: left;
}
.left-column h2:last-of-type, .left-column h3:last-child {
color: #000;
}
.right-column {
width: 75%;
float: right;
padding-top: 1em;
}
</style>
</head>
<body>
<textarea id="source">
name: inverse
layout: true
class: center, middle, inverse
---
# SSL/TLS basics
Ward Wouts<br>
---
# Agenda
1. SSL/TLS
1. MitM
1. Certificates
1. Handshake
1. Addons
1. More
---
# SSL, TLS, what's in a name?
---
layout: false
.left-column[
## SSL, TLS, what's in a name?
]
.right-column[
SSL was originally developed by Netscape as a way to protect communications between browsers and web servers.
Then the browser wars started... No way other browser makers were going to using something that was branded by Netscape.
SSL was from 1999(!) on developed further with the name TLS. So if you want to be pedantic, you can correct every use of `SSL` to `TLS`, and make lots of friends.
]
---
layout: false
.left-column[
## So what is it really?
]
.right-column[
Well, it's kind of a secure tunnel protocol over TCP. But it does not really fit into the OSI model. Which does not really fit with TCP/IP to begin with, so let's just not care and have a look.
]
???
$ openssl s_client -connect www.nu.nl:443
---
layout: false
.left-column[
## SSL/TLS versions
]
.right-column[
| Protocol | Published | Status |
| ----------- | ----------- | -------- |
| SSL 1.0 | Unpublished | Unpublished |
| SSL 2.0 | 1995 | Deprecated in 2011 (RFC 6176) |
| SSL 3.0 | 1996 | Deprecated in 2015 (RFC 7568) |
| TLS 1.0 | 1999 | Deprecation planned in 2020 |
| TLS 1.1 | 2006 | Deprecation planned in 2020 |
| TLS 1.2 | 2008 | |
| TLS 1.3 | 2018 | |
The reason for all deprecations has been security vulnerabilities in the protocols. We really, really should stop using those versions.
]
---
layout: false
.left-column[
## Why SSL/TLS?
]
.right-column[
SSL/TLS historically has two main purposes:
- Protecting traffic using encryption. Both its confidentiality as its integrity.
- Identifying the other side. This was what the lock in the browser URL bar used to be for, until it didn't make sense anymore.
Now, on a network you know and control completely there is no need for something like SSL/TLS. TCP can detect broken packets perfectly fine, so integrity is taken care of. There is noone snooping, because you are in control of the network and you already know what systems you are talking to: your own.
The internet is not such a network.
- Snooping can easily be done by any network operator using listener ports on network equipment.
- Traffic can be changed or diverted using a so called Man in the Middle attack
]
---
template: inverse
# Man in the Middle (MitM)
---
layout: false
.left-column[
## MitM
]
.right-column[
A Man in the Middle attack is a situation where Alice wants to talk to Bob.
<img src="alice-bob.png" width="100%" />
And Carol figures out a way to get in between.
<img src="alice-bob-carol.png" width="100%" />
This gives Carol full control over the conversation.
]
---
layout: false
.left-column[
## MitM
]
.right-column[
To prevent a MitM attack, we need at least the following:
- a way to establish that we are starting the conversation with the right end-point
- a way to make sure the conversation cannot be hijacked
The first problem is solved by using certificates.
The second is solved by negotiating a session key (during the TLS handshake) and encrypting the whole conversation using that key.
]
---
template: inverse
# Certificates
---
.left-column[
## Certificates
]
.right-column[
A certificate is in essence the public part of a public private key pair. With a bunch of information tacked on, such as:
- web site the certificate is for
- issuer of the certificate
- signature by issuer for the certificate
- ... much much more
]
---
.left-column[
## Signatures
]
.right-column[
So, how does a certificate get signed?
Or how does signing work in cryptography:
- take a message
- calculate a hash of the message
- encrypt the hash with your private key
Now anyone can verify the signature by:
- decrypting it with your public key
- creating a hash of the message
- comparing the decrypted hash with the calculated hash
Some variations on this scheme exist, but this is the gist.
]
---
.left-column[
## Certificate Authority (CA)
]
.right-column[
This is where the whole model gets real ugly.
A certificate authority is a party that can sign certificates in such a way that the browser can verify them.
The certificates of a certificate authority are, in the end, signed by root certificates.
Built in in your browser/OS is a list of root certificates. These are trusted by.... euh.... people who trust stuff... who we trust.... because.... euh.... This is just how it works, ok?
]
???
Show root certificate list
---
template: inverse
# Handshake
---
.left-column[
## Handshake
]
.right-column[
Or how to get to a state where an attacker that can watch all traffic, including the handshake, cannot snoop on or change the conversation.
This is where the client and server decide on:
- Which version of TLS/SSL to use
- Decide on which encryption (cipher suite) to use
- Establish the identity of the server using its certificate (and optionaly the client)
- Calculate a session key for the symmetric encryption following the handshake
]
---
.left-column[
## Handshake
]
.right-column[
<img src="tls-ssl-handshake.png" width="100%" />
.footnote[Borrowed from: (https://www.cloudflare.com/learning/ssl/what-happens-in-a-tls-handshake/)]
]
???
1. The 'client hello' message: The client initiates the handshake by sending a "hello" message to the server. The message will include which TLS version the client supports, the cipher suites supported, and a string of random bytes known as the "client random."
2. The 'server hello' message: In reply to the client hello message, the server sends a message containing the server's SSL certificate, the server's chosen cipher suite, and the "server random," another random string of bytes that's generated by the server.
3. Authentication: The client verifies the server's SSL certificate with the certificate authority that issued it. This confirms that the server is who it says it is, and that the client is interacting with the actual owner of the domain.
4. The premaster secret: The client sends one more random string of bytes, the "premaster secret." The premaster secret is encrypted with the public key and can only be decrypted with the private key by the server. (The client gets the public key from the server's SSL certificate.)
5. Private key used: The server decrypts the premaster secret.
6. Session keys created: Both client and server generate session keys from the client random, the server random, and the premaster secret. They should arrive at the same results.
7. Client is ready: The client sends a "finished" message that is encrypted with a session key.
8. Server is ready: The server sends a "finished" message encrypted with a session key.
9. Secure symmetric encryption achieved: The handshake is completed, and communication continues using the session keys.
---
.left-column[
## TLS1.3
]
.right-column[
You've probably not encountered TLS1.3 a lot yet. It is a big improvement however. With some new challenges.
- It's a lot quicker. One round trip (back & forth) in the handshake instead of two. Zero if the client has communicated with the website before.
- Outdated cryptography options have been dropped, among which:
- RSA key transport: Doesn't provide forward secrecy
- CBC mode ciphers: BEAST and Lucky 13 attacks
- RC4 stream cipher: Not secure for use in HTTPS
- Arbitrary Diffie-Hellman groups: CVE-2016-0701
- Export ciphers: FREAK and LogJam attacks
What's not to like? Well, that forward secrecy bit... It's great! But not everyone agrees.
.footnote[See also: https://www.cloudflare.com/learning/ssl/why-use-tls-1.3/<br>
And: https://blog.cloudflare.com/rfc-8446-aka-tls-1-3/]
]
---
.left-column[
## Forward secrecy
]
.right-column[
Forward secrecy (also named Perfect Forward Secrecy) means that a message cannot be decrypted after the fact. Not even when you have the private certificates of the webserver. This is awesome! This is what you have this whole crypto stuff for!
Except.... if you're a company and you want to inspect traffic after the fact. This is why some groups have created a variation of TLS1.3 that intentionally weaken it: ETS (or eTLS).
.footnote[See: https://www.eff.org/deeplinks/2019/02/ets-isnt-tls-and-you-shouldnt-use-it]
]
---
template: inverse
# Addons
---
.left-column[
## SNI
]
.right-column[
Traditionally only one certificate could be used for an HTTPS connection. As a consequence you need a dedicated IP address for each and every website using HTTPS. A solution was found in SNI (Server Name Indication). This is a mechanism where at the start of the handshake the connecting client specifies which servername it wants to connect to. Using SNI multiple websites can share on IP address and still use HTTPS connections.
The obvious problem with the SNI approach is that the name is send at the start of the handshake, so before encryption starts. An observer can sniff this traffic an learn to which site the client wants to connect. This also allows for blocking sites on this level. To work around this blocking, domain fronting has been used: start a connection with requesting a non-blocked site (i.e. google). Then after establishing the connection (when the inner HTTP connection is established) request the name that is actually wanted (i.e. signal).
Since mid 2018 ESNI (Encrypted SNI) is being rolled out, to solve the problems with SNI.
]
---
.left-column[
## DNS-Based Authentication of Named Entities (DANE)
]
.right-column[
So certificate authorities are a misguided concept at best. Is there a better way?
Well, actually: multiple. One of which is called DANE. DANE lets the owner of a domain certify the keys used by TLS by storing them in DNS. Which can be secured using DNSSEC. So, certificates without a CA being involved.
Additionaly, it lets the domain owner specify which CA is allowed to sign these certificates. So we'd need to trust the certificate authorities a lot less.
DANE is not used much, so this is mostly a theoretical fix. For obvious reasons CA's were against DANE. There is no support in Google Chrome, as DANE uses 1024-bit RSA, which Google want to eliminate from te browser.
]
---
.left-column[
## Let's encrypt
]
.right-column[
Once upon a time certificates were expensive. Because of this reason only organisations that could afford them bought certificates. This gave the illusion that when a website had a certificate it was trustworthy. With dropping prices for certificates it became more and more evident that this trustworthyness was an illusion[*]. Let's encrypt shattered the illusion completely by makeing certificates free and automatically deployed (using the ACME protocol). This has caused a huge uptake of secure connections on the internet, which in general is regarded a good thing.
.footnote[[*] In an attempt to keep the business model of certificates alive EV (Extended Validation) certificates were invented. In theory these certificate validate more than the site owner having a working creditcard.]
]
---
.left-column[
## Certificate pinning
]
.right-column[
In some situations we can do better than the protocols by themselves allow for. The protocols are made for generic software, such as browsers, that needs to work with any site. But when you're making dedicated software, such as an app, you can implement more stringent checks of certificates.
I.e. a banking app can check all information in a certificate, including the issuer. Often this is implemented mostly by string comparisons. Better is including the public root certificate of the issuer in the application.
These kind of checks are called certificate pinning.
]
---
.left-column[
## HSTS
]
.right-column[
Back to the MitM scenario. Traditionally when I type a URL in my browser the first thing that happens is an insecure HTTP request for the URL. With a bit of luck the browser then gets redirected to the safe HTTPS version. An attacker that can use a MitM attack on the connection can prevent this redirect.
For this reason HSTS (Hypertext Strict Transport Security) has been invented. This let's a website state "always use HTTPS to connect to me". Which the browser will remember, so don't let those certificates expire.
]
---
.left-column[
## HSTS preloading
]
.right-column[
The big problem with HSTS is that it only helps after visiting the target website for the first time. If an attacker can MitM the first connection they can prevent the HTTPS from ever being used and the HSTS header from ever being set. To counter this HSTS preloading was invented. This is a mechanism where sites are pre-registered in a browser as being HTTPS only sites. You can apply for this registration[*] and in the next browser version your site will be included in a built in list.
.footnote[[*] https://hstspreload.org/]
]
---
template: inverse
# More?
---
.left-column[
## More
]
.right-column[
There is much much more that we could cover, but won't. Including but not limited to:
- OCSP for online certificate statuses
- How OCSP is broken and the fix (stapled OCSP)
- Certificate transparancy logs/monitors/auditors
- ACME
- CRLs
- ...
]
</textarea>
<script src="https://remarkjs.com/downloads/remark-latest.min.js">
</script>
<script>
var slideshow = remark.create();
</script>
</body>
</html>