The system of certificates relies on trust. But how do we know who to trust? To make this process work, you need a certificate authority (CA). Certificate authorities are responsible for issuing, managing, and signing certificates. They attest to others that they can rely on the assertions made about the owner of the certificate, as well as the related public and private key. A consortium of certification authorities called the Certification Authority Browser Forum (or CA/Browser Forum) is responsible for standardizing the policies, guidelines, and technical requirements used by certificate authorities. Only CAs meeting these guidelines are considered for inclusion in trusted certificate stores.
A key responsibility of a CA is converting certificate requests (CSRs) into certificates. They do this by using their private key to create the signature on the final certificate. What makes a CA unique is that they hold a root certificate that is self-signed. That is, they are both the issuer and the subject. The public key for both fields is the same. These root certificates create a trust anchor; certificates that can trace their lineage back to a trust anchor become trusted.
Reputable CAs typically also issue an intermediate certificate which is signed by their root certificate. The intermediate certificate is also typically the one used to sign certificate requests. By using this instead of the root certificate, they reduce the risk of the root certificate becoming compromised. In addition, an intermediate certificate is easily revoked and reissued. A trusted root CA, on the other hand, is substantially harder to replace if it is compromised (especially on mobile devices, which may have longer update cycles).
Most computers come with a set of root certificates from globally recognized, trusted CAs. They typically also include (or cache) the related intermediate certificates. As mentioned before, only CAs that meet the Baseline Requirements from CA/Browser Forum are considered for inclusion. By having these certificates stored on the computer, any certificate can be validated to ensure that it originates from a trusted root CA.
There are multiple steps to validating a certificate:
- Validate the signature contained in the certificate.
- Confirm that the issuer has not revoked the certificate. This is done by looking at an extension called the Certificate Revocation List (CRL). This contains a URL that can be used to retrieve a list of certificate serial numbers that have been revoked.
- Use the issuer’s identifier (authority key) from the certificate to identify the issuer’s certificate.
- Validate the issuer certificate, repeating this process for each certificate’s issuer until a trusted root CA is reached (or no trusted root is found, causing the certificate to be rejected).eam
Every time a certificate is used in any programming language (directly or as part of a protocol, such as HTTPS), these steps ensure that the certificate is valid and can be used safely. The challenge is that there may be multiple sources for the certificates that have to be considered.
Applications, programming languages, and CAs
For various reasons, applications and programming languages sometimes choose to use their own set of certificates (often based on collection provided by the Mozilla Foundation). For example:
- Node.js includes a hardcoded set of certificates. Python defaults to using the operating system’s libraries, but can be compiled to use a different implementation.
- Go tries to find certificates on Linux by examining multiple locations; it uses the OS stores for Windows and macOS.
- The .NET runtime typically relies on the operating system.
- Java includes its own trusted keystore, but can be configured to utilize the operating system.
Many languages support OpenSSL, so they frequently support environment variables that can point to a a folder of trusted certificates (SSL_CERT_DIR
) or a master PEM file containing the trusted certificates (SSL_CERT_FILE
). For those that don’t use OpenSSL, they often provide a mechanism to add certificates to the validation process. This means that depending on the language(s) used, an application may determine its trust from a specific set of certificates rather than the set provided by the operating systems.
In addition, some tools (such as curl
) can manage their own certificate store. To add to the challenges, the tools may utilize just the signature,
ignoring any additional constraints contained in the certificate or a parent issuer. As a result, they may not always do a complete validation. These tools may not ensure that the certificate constraints are properly honored, allowing certificates to do more than intended.
To add to the complexity, browsers and proxies can also have their own trust stores. For the entire system to work properly, each component must have access to any certificates that must be trusted.
As you can see, altering the list of trusted CAs can be very time consuming. So why would anyone try?
The self-signed problem
For many years, certificates were expensive an burdensome to maintain. The CAs charged a premium for their service and certificates required periodic renewals. As a result, many enterprises implemented their own internal certificate authority. This allowed them to distribute their own certificates and secure internal servers without having to purchase certificates from a trusted authority. They create their own self-signed certificate; this file is then added to the trusted stores to create a new trusted CA.
Security teams may feel this provides extra security, but most security teams miss vital steps in their implementation. Certificate management is not intended for those that aren’t well-versed in the X.509 standard and its security implications. Once implemented, it often requires heavy configuration in multiple across the networked systems. Multiple certificate stores need to be updated. If any one is missed, it can lead to connectivity problems.
Once a system like this is configured, many enterprises continue to rely on their self-signed certificates and find it difficult to get away from them. Some will even claim that it increases security, despite the fact that all of the extra configuration required is the first indication that their working against accepted patterns and practices.
Installing updated CAs is fairly easy at the OS level. As we saw before, applications may have other ways to determine which CAs are trusted. Most security teams implementing a custom CA fail to understand the level of effort to secure the applications. In most cases, they assume that updating the operating system is sufficient.
When this process creates friction, it’s not uncommon to see developers or infrastructure teams disable SSL validation. Unfortunately, that escalates the issues. If validations are disabled, then the affected tools will trust all certificates inherently. This allows man-in-the-middle attacks and effectively eliminates the TLS-based security on your networks. This can impact browsers, applications, firewalls, VPNs, and even identity management. If developers accidentally ship their code with validation disabled, it can put customers at risk and create a substantial liability risk.
As you can see, managing and deploying your own internal certificate authority has numerous ways to create serious challenges (and security risks) for your teams! Security experts with a background in PKI will always encourage teams to avoid going down this path. It brings nothing but trouble and risk.
Securing the network
Because these challenges often created compromised networks or security, a number of organizations including EFF, Mozilla, Akamai, and Cisco created a non-profit certificate authority (Let’s Encrypt) to provide X.509 certificates at no charge. In addition, they provide automated support for certificate request and issuance. This allows them to utilize short-lived certificates (90 days), increasing the level of security. Before the certificates expire, the automation is used to request a new certificate. By making the expiration more frequent, it makes it less likely that the keys for a given site can be compromised and ensures that improperly issued certificates are invalidated by tools and languages quickly (even those that otherwise ignore the certificate revocation list).
Over the last few years, additional CAs have started offering their own free certificates. As a result, there are now multiple options for issuing certificates that terminate in a well-known trust anchor. As a result, its increasingly rare to have a valid reason to consider managing your own Public Key Infrastructure (PKI) and certificate authority.
That said, in some industries (such as banking), there are stricter security requirements for certificates. This can include extended validation (EV) and additional insurance by the issuing authority in case their certificates are compromised. Companies subject to these requirements typically can’t use services like Let’s Encrypt for their public sites or services. In some cases, they may even need to buy EV certificates for their internal systems. All of that said, services like Lets Encrypt are still preferable and typically more secure for internal development than a self-managed CA.
Signed and delivered
So there you have it: certificates in a nutshell. Hopefully this has given you some insights into the certificate process and the complexities of self-signed certificates. Thankfully, companies have options to avoid this complexity. Sticking with a trusted CA means they can just let certificate management be something magical that happens behind the scenes. 😄🪄🐇