Learn more >
by Sam Roberts Published March 19, 2019
TLS1.3 is a bigger deal than you might think. The version number gives the impression it’s only a minor update, but that’s not the case. It’s a major protocol update, even though it masquerades on the wire as TLS1.2 for interoperability. Security specialists are excited, and I’ll try to explain why everyone should plan to migrate to TLS1.3 as soon as possible.
TLS1.2 is currently the maximum TLS protocol version supported by Node.js LTS releases. In order to fix this, I’ve been actively working over the last few months on getting TLS1.3 support into Node.js. Node.js leverages OpenSSL for its cryptography and, therefore, the prerequisite for this work was an OpenSSL version which supports TLS 1.3. The TLS1.3 specification was published in August 2018, and support for TLS 1.3 was only made available in OpenSSL in September 2018, as part of OpenSSL 1.1.1.
The first step was updating Node.js to the latest version of OpenSSL 1.1.1, which, among other improvements, has support for TLS1.3. This was released in Node.js 11.9.0 on January 30, 2019. It should make it into Node.js 10.x in April, 2019.
See my previous blog post, “OpenSSL 1.1.1 has landed in Node.js: Why it’s important for Node.js LTS releases” on why OpenSSL 1.1.1 was important for Node.js Long term support (LTS).
In this blog post, we focus on what it means for TLS1.3 support.
After updating Node.js to use the latest version of OpenSSL, we now had to update Node.js to handle differences introduced by TLS 1.3. While OpenSSL 1.1.1 is ABI and API compatible with OpenSSL 1.1.0, it didn’t work seamlessly for Node.js when TLS1.3 is used instead of TSL 1.2.
As I discovered, TLS1.3 has too many differences at the protocol level for it to be entirely hidden by the API. The handshake is different, the number of session tickets exchanged is different, the timing of many important events, such as ticker availability and handshake completion are different. Even differences in packet order and timing caused subtle bugs
to surface in Node.js when it was used with TLS1.3.
I’ve spent the beginning of 2019 working through the differences which leak through the API, and have a pull request open. Hopefully TLS1.3 will be released in Node.js 11.x soon.
It seems counterintuitive, but TLS 1.3 is a simpler protocol than TLS 1.2. As a result, it’s more secure, easier to configure, and negotiates sessions more quickly.
The larger number of options in TLS1.2 can make it hard to debug interoperability problems. For example, TLS1.3 has only 5 cipher suites, whereas Node.js has 57 TLS1.2 cipher suites that are enabled by default (even after the insecure ones have been disabled!). That’s a huge difference.
In addition, only three of of the five cipher suites supported by TLS 1.3 are enabled by default. The other two are designed specifically for resource-constrained systems such as those used for the Internet Of Things (IoT), and aren’t expected to be in common use.
Now let’s dive into the details of some of the important changes. These include:
Assured forward secrecy: Forward secrecy means that if an attacker manages to obtain the private key used to set up an earlier session, they still will not be able to recover the content of that session. TLS 1.2 could not provide forward secrecy when using RSA key exchange, and you had to opt-in for the feature when using (EC)DH key agreement. With TLS1.3, all cipher suites provide forward secrecy because they use ephemeral (EC)DH key agreement.
No RSA key agreement: TLS used to support two ways to agree on a shared key in order to protect the data exchanged during a session: RSA, and (EC)DH. RSA key agreement has a history of bugs and, as metioned above, did not support forward secrecy. Support for RSA has been removed from the key agreement step which is now always done with ECDH (OpenSSL doesn’t support DH). This simplifies the handshake, the protocol, and the cipher suites. Note that RSA can still be used to help validate the identify of the two parties sharing data through the session.
Safer Cipher Options: TLS1.2 supports a number of ciphers, like RC4 and DES, that are now considered too weak to be used safely. Node.js already disables most of them in its default configuration, but they still exist and can be used if you are using TLS 1.2. TLS1.3 supports only AES256, AES128, and CHACHA20 as ciphers; they are currently considered strong.
Safer cipher modes: Symmetric ciphers need to be used in “modes” that allow them to encrypt streams of data, not just single blocks. TLS1.2 uses cipher modes that were thought secure at the time of its design, but that now have a
history of being sucessfully attacked. TLS1.3 supports only AEAD (authenticated encryption with additional data), cipher modes.
If you want more detail on how TLS 1.3 improves on TLS 1.2 and the impact on Security, cloudfare provides an in-depth article on the history of TLS attacks and how TLS 1.3 addresses them.
TLS1.3 is not yet a year old, and browser support is not yet wide enough to allow you to disable TLS1.2 for deployed web servers (see caniuse for more info). However, you can enable it so you can use it when it’s ready.
Support for TLS 1.3 is improving quickly. You should track progress in order to decide when this might be possible to restrict usage to TLS 1.3 for your public-facing servers. On the other hand, in a microservices environment or an internal/corporate network with clients and servers which are under your control, it might be possible to restrict support to TLS1.3 today. Depending on your environment and security needs, you might want to consider using TLS 1.3 now.
I hope I’ve given you insight into why you want to move towards TLS 1.3, the benefits that TLS 1.3 offers, and what you should be thinking about with respect to migration.
The good news is that there is progress on getting support for TLS 1.3 into Node.js, and you should be able to starting using it soon (hopefully as soon as October when Node.js 12.x goes into LTS). In my next blog post, I give you more in-depth insight and advice on what you need to do as part of your migration to TLS 1.3.
OpenSSL 1.1.1 is now included in Node.js. Learn what it means for you and how it affects the Node.js LTS…
Back to top