HTTPS

and TLS, ciphersuites, PFS

and HSTS, HPKP, OCSP

and CRL, OneCRL, CT, CAA

and maybe a bit of web pki if we have time


Find these slides at goo.gl/DHLPmA

$whoami
Julien Vehent       @jvehent

CountFailure
3526remove cipher RC4-SHA
2530remove cipher IDEA-CBC-SHA
1964remove cipher ECDHE-RSA-RC4-SHA
716remove cipher RC4-MD5
174remove cipher don't use a key smaller than 2048bits (RSA) or 256bits (ECDSA)
20MD5WithRSA is a bad certificate signature

Let's fix it!

  1. Get a decent cert
  2. Fix those ciphersuites
  3. Enable OCSP Stapling
  4. Set up HSTS
  5. For the paranoids, set up HPKP
  6. Monitor!
  7. What if we ever need to revoke?
  8. Maybe don't use just any CA...

1. Get a decent cert

Automated Certificate Management Environment


lego
-d bsidestampa.vehent.org
-k ec256
--email="julien@vehent.org"
--path="/etc/letsencrypt/"
new
                    

https://github.com/xenolf/lego

Any reasons NOT to use
Let's Encrypt?

No! It's just as safe, if not safer, than other CAs.

But: beware of dangling domains!

2. Fix those ciphersuites

Mozilla's Modern set of Ciphersuites

server {
  ssl_protocols TLSv1.2;
  ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:
               ECDHE-RSA-AES256-GCM-SHA384:
               ECDHE-ECDSA-CHACHA20-POLY1305:
               ECDHE-RSA-CHACHA20-POLY1305:
               ECDHE-ECDSA-AES128-GCM-SHA256:
               ECDHE-RSA-AES128-GCM-SHA256:
               ECDHE-ECDSA-AES256-SHA384:
               ECDHE-RSA-AES256-SHA384:
               ECDHE-ECDSA-AES128-SHA256:
               ECDHE-RSA-AES128-SHA256';
  ssl_prefer_server_ciphers on;
}
                    

TLS without PFS

  1. Client starts a TLS handshake
  2. Client encrypts a session secret with the server's public key
  3. Server decrypts the session secret
  4. Client and server encrypt data with the session secret


Problem: one private key decrypts all session secrets, and thus all data, from past and future connections.

TLS with PFS

  1. Client starts a TLS handshake
  2. Server picks DHE or ECDHE, sends the necessary elements
  3. Client and Server agree on an ephemeral session key
  4. Server's private key cannot decrypt the session key

3. Enable OCSP Stapling










3. Enable OCSP Stapling


# OCSP Stapling ---
# fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;

# verify chain of trust of OCSP response using Root CA and Intermediate certs
ssl_trusted_certificate /path/to/root_CA_cert_plus_intermediates;

# local DNS resolver
resolver 127.0.0.1;
                    

4. Set up HSTS


# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
add_header Strict-Transport-Security max-age=15768000;
                    

HSTS pins are cached in your browser profile


$ cat firefox/$id.personal/SiteSecurityServiceState.txt
gist.github.com:HSTS              1    17012  1501450947634,1,1
accounts.firefox.com:HSTS         0    16874  1473537309356,1,1
www.box.com:HSTS                  0    16944  1495509238443,1,0
snippets.cdn.mozilla.net:HSTS     34   17196  1517352255089,1,0
...
					

HSTS pinned sites go straight to HTTPS

browsers don't attempts to connect to HTTP at all

4bis. HSTS Preloading

If you can guarantee all your subdomains will ALWAYS be HTTPS, preloading allows you to feed that information to Firefox and Chrome.

Benefit: No need for HTTP redirect to HTTPS on the first connection!

https://hstspreload.org

5. Set up HPKP

Disclaimer: Here be Dragons!

What's Public Key Pinning?

The Public Key Pinning Extension for HTTP (HPKP) is a security feature that tells a web client to associate a specific cryptographic public key with a certain web server to decrease the risk of MITM attacks with forged certificates.

HPKP contains a list of trusted public keys


Public-Key-Pins: max-age=5184000;
  pin-sha256="WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=";
  pin-sha256="r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=";
  pin-sha256="YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg=";
  pin-sha256="sRHdihwgkaib1P1gxX8HFszlD+7/gTfNvuAybgLPNis=";
					

The value is a hash of the public key


wget https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem

openssl x509 -in lets-encrypt-x3-cross-signed.pem \
  -pubkey -noout |
  openssl rsa -pubin -outform der |
  openssl dgst -sha256 -binary |
  openssl enc -base64

YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg=
					

Now, the dragons

You can't change your mind about a pinned cert until clients expire the pin. If you lock yourself into a CA, you must stay with it for a while.

Don't pin end-entity (server) certs, only pin intermediates and roots.

How are we doing?

And the HTTP Headers?

6. Monitor!


$ go get -u github.com/mozilla/tls-observatory/tlsobs

$ tlsobs -r -targetLevel modern bsidestampa.vehent.org
[...]
--- Analyzers ---
* Mozilla evaluation: modern

$ echo $?
0
					

Revocation: CRL & OCSP

Browsers' own mechanisms:
OneCRL & CRLSet

  1. Browser security teams detect a bad cert (end-entity, intermediate or root)
  2. Public key hash of the cert is added into a big list of blocked certs
  3. List gets distributed to all user agents via browser's own infrastructure

Benefit: deterministic distribution, much more reliable than OCSP or CRL.

Trusting the right CAs

Pick two CAs that...

then use HPKP to pin your sites to those 2 CAs

Thanks!

Ask your questions on Twitter: @jvehent