Let's Encrypt SCTs in Certificates

Wednesday 4th April 2018

As of 29th March 2018, all certificates issued by Let's Encrypt now include a Signed Certificate Timestamp (SCT) embedded in the certificate in the form of an X.509 v3 extension.

Skip to Section:

Let's Encrypt SCTs in Certificates
┣━━ Upcoming Chrome Certificate Transparency Requirements
┣━━ Expect-CT HTTP Response Header
┗━━ Conclusion

Below is part of the SSLLabs report for my site that is using a recently issued Let's Encrypt certificate, showing that Certificate Transparency (CT) is working, and that the SCT is embedded in the certificate:

Let's Encrypt certificates have always been published to CT logs, however by default there was no straightforward way to serve SCTs. Now SCTs are included by default in all newly issued Let's Encrypt certificates. Please see the original announcement by Let's Encrypt: https://community.letsencrypt.org/t/signed-certificate-timestamps-embedded-in-certificates/57187

Upcoming Chrome Certificate Transparency Requirements

This new Let's Encrypt feature is in good time for Chrome's upcoming CT requirements, which state that all certificates issued after 30th April 2018 must be compliant with the Chromium CT policy:

Chrome will require that all TLS server certificates issued after 30 April, 2018 be compliant with the Chromium CT Policy. After this date, when Chrome connects to a site serving a publicly-trusted certificate that is not compliant with the Chromium CT Policy, users will begin seeing a full page interstitial indicating their connection is not CT-compliant. Sub-resources served over https connections that are not CT-compliant will fail to load and will show an error in Chrome DevTools...

Source: https://groups.google.com/a/chromium.org/d/msg/ct-policy/wHILiYf31DE/iMFmpMEkAQAJ

This essentially means that all certificates issued after 30th April 2018 need to prove their compliance with the CT requirements by serving a valid SCT to clients in either of the following forms:

Websites/servers that fail to do this will no longer be considered trusted by Chrome and Chromium. However, in most cases, the Certificate Authority (CA) will resolve this by issuing certificates with the SCTs embedded (as Let's Encrypt have), so for the average website owner, they likely will not have to do anything. Certificates issued before the deadline will continue to work as normal as they are not subject to these new requirements.

Below is an example of the full-page error screen as described in the Google Chrome Team's announcement that will be shown instead:

In order to simulate enforced certificate transparency before the 30th April 2018 deadline, you can add your site to the Expect-CT list in your local version of Chrome at chrome://net-internals#hsts:

Make sure to check the 'Enforce' box. This will now simulate enforced certificate transparency for the domain you specified in your local browser only. In order to revert these local changes, enter your domain into the 'Delete domain security policies' form on the same page.

Expect-CT HTTP Response Header

Now that Let's Encrypt is issuing certificates with the SCT included, it makes it significantly easier to deploy a working Expect-CT HTTP response header. This header allows you to opt-in to the new requirements early, as well as providing a reporting functionality using the report-uri directive.

An example of a valid Expect-CT header is as follows:

Expect-CT: max-age=63072000, enforce, report-uri="https://report-uri.example.com/ct/"

This will instruct browsers to cache the policy for 63,072,000 seconds (2 years), enforce the policy strictly (rather than being report-only), and report violations to the specified URI.

Going straight in at a 2 year enforcement policy is perhaps a bit overzealous, especially for a newer technology. If something goes wrong and you have to go back to using a non-CT-compliant configuration, you risk locking users out of your site for a prolonged period of time. While this is very unlikely to happen, especially given that Chrome and Chromium are going to be automatically enforcing this at the end of April anyway, it's still better to play it safe and increment the max-age value of your policy. Start out at a very short amount of time (a few minutes) and check for issues. Once your happy that there are no problems, raise it to 1 day, then 1 week, etc.

It is also important to note that as per the Expect-CT draft specification, your client will not cache the policy if the connection is not CT-compliant. This prevents you from accidentally setting an Expect-CT policy when the connection is not CT-compliant in the first place:

If the connection does not comply with the UA's CT Policy (i.e. is not CT-qualified), then the UA MUST NOT note this host as a Known Expect-CT Host.

Source: https://tools.ietf.org/html/draft-ietf-httpbis-expect-ct-03#section-2.3.1


I have reissued all of my Let's Encrypt certificates in order to make use of the new automatically included SCTs, and have also enabled the Expect-CT security header on my site with the enforce directive set.

It'll also be interesting to keep an eye on CT up until and beyond the deadline - it's another piece of the TLS puzzle solved hopefully.

This article is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.