Staying on top of TLS attacks
CloudFlare makes extensive use of TLS connections throughout our
service which makes staying on top of the latest news about security
problems with TLS a priority. We use TLS both externally and
internally and different uses of TLS have different constraints.
Broadly there are three ways we use TLS: to handle HTTPS connections
from web browsers visiting web sites that use CloudFlare, to make
HTTPS connections from our network of datacenters to our customers’
web servers, and internally within our network.
This week, news of a new type of attack against the RC4 cipher used
for some TLS connections has made us reevaluate (once again) all our
use of TLS and specifically which ciphersuites we are using.
This blog post gives some background on TLS and ciphersuites, the most
recent attack and how we are configuring our systems to keep our
customers (and their customers) as safe as possible.
TLS and Ciphersuites
When two computers want to communicate securely using TLS, one of them
(referred to as the client) connects to the other (the server) and
they enter a negotiation about what encryption method to use. Central
to that communication is an agreement between client and server on
which ciphersuite will be used. The ciphersuite specifies precisely
the type of encryption that will be used between client and server.
For example, when you visit a web site such as
https://cloudflare.com/ using HTTPS a TLS
connection is established between your web browser and the CloudFlare
web server. Your web browser starts the TLS connection by telling the
web server which ciphersuites it supports: it tells the web server
which types of encryption it is able to use.
The list of available ciphersuites varies from browser to browser and
from version to version. The University of Hannover has a little web
site that will show you which ciphersuites your web browser
supports. To use it just visit
https://cc.dcsec.uni-hannover.de/.
For my browser, the latest version of Google Chrome, the list of
suites is as follows. The order gives the web browser’s preference for
ciphersuites. For example, it would prefer to use
ECDHE-ECDSA-AES256-SHA instead of ECDHE-RSA-AES256-SHA.
ECDHE-ECDSA-AES256-SHA
ECDHE-RSA-AES256-SHA
DHE-RSA-CAMELLIA256-SHA
DHE-DSS-CAMELLIA256-SHA
DHE-RSA-AES256-SHA
DHE-DSS-AES256-SHA
ECDH-RSA-AES256-SHA
ECDH-ECDSA-AES256-SHA
RSA-CAMELLIA256-SHA
RSA-AES256-SHA
ECDHE-ECDSA-RC4128-SHA
ECDHE-ECDSA-AES128-SHA
ECDHE-RSA-RC4128-SHA
ECDHE-RSA-AES128-SHA
DHE-RSA-CAMELLIA128-SHA
DHE-DSS-CAMELLIA128-SHA
DHE-DSS-RC4128-SHA
DHE-RSA-AES128-SHA
DHE-DSS-AES128-SHA
ECDH-RSA-RC4128-SHA
ECDH-RSA-AES128-SHA
ECDH-ECDSA-RC4128-SHA
ECDH-ECDSA-AES128-SHA
RSA-SEED-SHA
RSA-CAMELLIA128-SHA
RSA-RC4128-SHA
RSA-RC4128-MD5
RSA-AES128-SHA
ECDHE-ECDSA-3DES-EDE-SHA
ECDHE-RSA-3DES-EDE-SHA
DHE-RSA-3DES-EDE-SHA
DHE-DSS-3DES-EDE-SHA
ECDH-RSA-3DES-EDE-SHA
ECDH-ECDSA-3DES-EDE-SHA
RSA-FIPS-3DES-EDE-SHA
RSA-3DES-EDE-SHA
Each web server will have a similar list of ciphersuites and during
the TLS handshake (at the start of a TLS connection) the client and
server will agree on a ciphersuite that they both understand taking
into account the order of preference of the client and server.
When I connect to https://cloudflare.com/
my browser and the CloudFlare web server agree to use
ECDHE-RSA-RC4128-SHA. That cryptic string has a lot of information in
it. It explains how the browser and server will exchange or agree on
encryption keys and how the actual web browsing I do will be
encrypted.
It breaks down as follows:
ECDHE means that the client and server will agree on encryption keys
using Ephemeral Elliptic Curve Diffie-Hellman.
RSA means that the client will verify that the key is valid using the
RSA algorithm to communications.
RC4128 means that the actual encryption of my web browsing session
will be performed using the RC4 algorithm with a 128-bit key (that’s
the key that the client and server will have agreed using ECDHE-RSA).
And finally SHA means that the SHA algorithm will be used for securely
hashing parts of the TLS messages.
CloudFlare’s server configuration for TLS ciphersuites is set in
nginx
(which we use extensively) with the following configuration command:
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-RC4-SHA:
ECDHE-RSA-AES128-SHA:AES128-GCM-SHA256:RC4:HIGH:
!MD5:!aNULL:!EDH:!CAMELLIA;
ssl_prefer_server_ciphers on;
(Note that a previous version of this blog post had the wrong configuration
caused by your truly copy/pasting the wrong thing).
That results on the server offering the following ciphersuites (you
can check this yourself using the SSL Labs
Report):
ECDHE-RSA-AES128-GCM-SHA256
ECDHE-RSA-RC4128-SHA
ECDHE-RSA-AES128-CBC-SHA
RSA-AES128-GCM-SHA256
RSA-RC4128-SHA
ECDHE-RSA-AES256-GCM-SHA384
ECDHE-RSA-AES256-CBC-SHA384
ECDHE-RSA-AES256-CBC-SHA
RSA-AES256-GCM-SHA384
RSA-AES256-CBC-SHA256
RSA-AES256-CBC-SHA
ECDHE-RSA-3DES-EDE-CBC-SHA
RSA-3DES-EDE-CBC-SHA
ECDHE-RSA-AES128-CBC-SHA256
RSA-AES128-CBC-SHA256
RSA-AES128-CBC-SHA
The CloudFlare server’s preference is ECDHE-RSA-AES128-GCM-SHA256 but
unfortunately it is not widely supported. Yet. I’ll come back to that
ciphersuite later. So, my browser and the server agreed to use the
server’s second preference, ECDHE-RSA-RC4128-SHA.
Forward Secrecy
You’ll notice that we’ve configured the CloudFlare server to prefer
ciphers that use ECDHE. That’s because, unlike the ciphers that start
with RSA, they offer forward
secrecy. To
understand forward secrecy it’s best to start by understanding systems
that don’t offer it, such as RSA.
When using RSA, the server’s public key is used to encrypt a secret
created by the client, the web browser. Because the server has the
private key it can read the secret and both the client and server then
know a shared secret that they can use for encryption. But the
server’s public RSA key is part of the server certificate and is
typically very long lived. It’s not uncommon for the same public key
to be used for months or years (the current CloudFlare RSA key isn’t
set to expire until December 5, 2013). That creates a potential
problem: if an SSL server’s private key were to leak or be stolen all
connections made in the past using that key would be vulnerable. It
would be enough that someone had recorded your SSL connections: with
the private key they could all be decrypted.
But forward secrecy with ECDHE means a fresh public key is created for
every single connection. That means that an adversary would need to
break the key for each connection individually to read the
communication. And the keys are ephemeral: the server forgets them
when connections are done. So there’s nothing to leak.
So, we’ve prioritized those ciphers because they offer a higher level
of long term security for people contacting CloudFlare sites.
I mentioned above that the ciphersuite that CloudFlare prefers is
ECDHE-RSA-AES128-GCM-SHA256 and that ECDHE is preferred because it
offer forward secrecy. The next part of the ciphersuite is RSA. In the
ECDHE scheme that’s just used to prove the identity of web server, and
not to secure the connection, so the concerns above about leakage of
the private key don’t apply.
The next part is AES128-GCM. This is the cipher that will be used to
encrypt the actual HTTP requests and responses encrypted in the TLS
connection. This particular cipher is using
AES with
a 128 bit key in Galois/Counter
Mode. Unfortunately,
this very strong cipher is only part of
TLSv1.2
which is not widely supported by web browsers. CloudFlare has it
configured ready for the day when it is supported because it is very
secure.
Double Trouble
Since TLSv1.2 isn’t widely supported, the two popular ciphers used to
secure the data sent across a TLS connection are
RC4 and AES (in CBC
mode). Both
have flaws and both have attacks that could be used against them. Very
recently a new attack against RC4
was announced that could allow an attacker to recover parts of the
original HTTP message (such as a cookie value) when RC4 is used.
The CBC mode ciphers have attacks called
Lucky-13 which we’ve
discussed
before
and BEAST
which we’ve also talked
about.
Because BEAST and Lucky-13 both attack CBC-based ciphers, CloudFlare
decided in the past to prioritize the use of the other cipher:
RC4. Unfortunately, the latest attack goes after RC4. So now both the
popular ciphers have published flaws. The sooner browser vendors move
to TLSv1.2 and away from RC4 and AES in CBC mode the better.
RC4 Keystream Biases
The new RC4 attack is based on biases in the RC4 keystream. To
understand how the attack works it’s necessary to understand a little
of how RC4 works.
RC4 operates by generating a pseudorandom stream of bytes of data
called the keystream. These bytes are XORed with the information to be
encrypted and the result is transmitted. For example, suppose that the
word SECRET is to be sent using RC4.
In ASCII, SECRET is the following six hexadecimal numbers:
S E C R E T
83 69 67 82 69 84
Suppose that RC4 generates the following six bytes in the keystream:
85 B8 D6 6B C7 51
To encrypt SECRET the keystream is XORed with the word SECRET byte by
byte and the result, 06 D1 B1 E9 AE D5, is transmitted.
S E C R E T
Message: 83 69 67 82 69 84
Keystream: 85 B8 D6 6B C7 51
XOR -----------------
Ciphertext: 06 D1 B1 E9 AE D5
(This XOR technique dates all the way back to 1919 with the Vernam
Cipher; read the
Wikipedia article for a basic introduction to the use of XOR in
ciphers. RC4 itself, of course, is much more recent.)
The exact pseudorandom sequence that RC4 generates depends on the key
used. As long as both client and server have the same key they can
generate the same keystream and perform the same set of XOR operations
to encrypt and decrypt data. That’s because XOR is its own inverse: if
you do Z = X XOR Y and then do Z XOR Y you get back to X.
So, when 06 D1 B1 E9 AE D5 is received on the other side it performs
the same XOR operation with the same keystream sequence to recover the
original message.
Ciphertext: 06 D1 B1 E9 AE D5
Keystream: 85 B8 D6 6B C7 51
XOR -----------------
Message: 83 69 67 82 69 84
S E C R E T
But it’s vital that the keystream be random so that an eavesdropper
can’t obtain any useful information from the ciphertext. If the random
stream contained biases (such as some numbers that came up more often
than others) it would be possible to use probability to predict what
the original, unencrypted message was.
That’s what the latest RC4 attack shows. Specifically, there are
biases in the first 256 bytes of keystream generated by RC4. Those
first bytes are likely to be used to encrypt the start of an HTTP
request and may include sensitive information such as a cookie used
for logging into a web site.
The attack works by causing the same request to occur over and over
again (for example, using a piece of JavaScript to contact the same
web site repeatedly). On each connection the same request (with the
same cookie) will be encrypted with RC4. A different key is used each
time which results in a different keystream, but over many encryptions
any biases in the keystream will show up as certain numbers appearing
in the ciphertext more or less often than others (because some numbers
appeared more often than others in the keystream).
The numbers that make up the RC4 keystream should be totally
random. So if the same message, such as the word SECRET above, is
encrypted over and over again with RC4 the resulting ciphertexts
should be totally random: the probability of each number between 00
and FF appearing should be the same. If you encrypted SECRET over and
over again with RC4 and counted the number of occurrences of 00 to FF
in the ciphertext they should be roughly equal. Just as if you roll a
fair die over and over again and count how many times the numbers 1 to
6 appear they should be equal.
Unfortunately, the researchers have discovered that the first 256
bytes of the keystream are not completely random and over time a
pattern emerges.
For example, here’s their chart showing the probability of each number
appearing as the first number produced in the RC4 keystream. This
should be completely flat with each number being equally
probable. It’s not. That means that if the same message were encrypted
over and over again it would be possible to determine (with a certain
probability) what the original first character was.
With many repeated tests, just as rolling a loaded die many times
would show which numbers come up most often, the attack can see which
ciphertext numbers come up most frequently and match that pattern to
the pattern in the keystream. From that a simple XOR can reveal the
original message.
And the same authors describe another attack based on biases in
adjacent numbers in the keystream that works at any point, not just in
the first 256 bytes.
So both of the widely supported ciphers have faults. These faults are
exploitable by attackers under the right conditions; they are not
theoretical attacks, but they are hard to pull off. Nevertheless,
CloudFlare will be happy when we can move away from RC4 and CBC-based
ciphers and put Lucky-13, BEAST and others behind us.
Protecting Internal Systems
While CloudFlare has to wait for browser makers to implement the
latest and safest cryptography, we don’t have to wait for any of our
internal systems.
CloudFlare uses TLS internally extensively (and between CloudFlare
software components like
Railgun) and has recently done
an audit of all uses of TLS to ensure that the best ciphers are in
use. And so for situations where CloudFlare controls both the client
and server we are deprecating use of TLSv1.1 and switching to TLSv1.2
with ECDHE-RSA-AES128-GCM-SHA256 as the current cipher of choice.
As the world of cryptography and TLS changes CloudFlare will keep
updating its systems to keep them at the forefront of the available
research.
No comments yet.