tl;dr We looked at 7 billion TLS certificates and found widespread private key reuse. We also looked at 65 million active GitHub users' SSH keys and found the same issue. Traditional username/password reuse gets lots of attention, but private reuse deserves some too.
Username and password reuse is a massive security issue. Attackers exploit this by launching credential stuffing attacks, using leaked login details to breach other accounts that share the same password. This problem is so prevalent that an entire industry has sprung up to address it - password managers. Given how dangerous password reuse is…
Why do we treat private key re-use for TLS certificates and SSH as acceptable? Private keys are just as, if not more, critical to secure communication, and re-using them, especially once they’ve been compromised, creates a huge attack surface.
We discovered cases where keys were revoked due to compromise, yet those same keys were later used to create new TLS certificates. We also found widely-used frameworks that, by design, reuse private keys across multiple certificates.
In this post, we'll discuss why private key reuse is dangerous, why it has been normalized, and what steps software engineers can take to address it.
The Problem with Reusing Private Keys
TLS certificates are the backbone of all secure browsing on the internet. They verify a server’s identity and enable encrypted communication. When you create a TLS certificate, you’re asked to supply a private key (ex: a RSA key). There’s nothing stopping you reusing the same private key for multiple TLS certificates. And much like a password, if your private key is compromised, your TLS certificate(s) are also at risk. So what?
If an attacker gains access to a private key, they can use it to impersonate servers, decrypt sensitive data, and even hijack user sessions.
In one of the most high profile incidents of private key theft, hackers compromised the Certificate Authority (CA) DigiNotar’s private key and used it to issue fraudulent TLS certificates. The result? Hundreds of thousands of Iranian citizens browsed to attacker-controlled servers and had their data, like email sitting in their gmail, stolen.
What do I do if my private key is stolen?
Certificate owners have two options when a private key is compromised: they can submit the certificate to be listed on the Certificate Revocation List (CRL) or use the Online Certificate Status Protocol (OCSP) to verify its revocation status.
When revoking TLS certificates via the CRL, users must specify a reason for the revocation. The most popular reason is "unspecified"; however, some certificate administrators own up to having had their key compromised and explicitly list "key compromised" as the reason.
But both the CRL and OCSP aren’t ideal. Interacting with a CRL or using the OCSP introduces additional latency and failure points (among other downsides).
In fact, the challenges with the CRL and OCSP led the community to pursue short-lived certificates and create ACME.
Why is this so common?
The ACME protocol enables CAs and server owners to automate the verification and issuance of TLS certificates.
Source: https://www.sectigo.com/resource-library/what-is-acme-protocol
By making it super easy (and fast) to issue and renew a TLS certificate, server owners can use short-lived (ex: 90 day) certificates. This shortens the window that an attacker with access to a private key could exploit.
Unfortunately, private key re-use across multiple certificates renders some of these benefits null, especially if the same key is reused for over a decade (nudge, nudge, hint, hint - that happens a lot more than we’d like to think).
One of the reasons private key reuse is so common is because some ACME frameworks make it the default behavior. Developers might not even realize that they are reusing private keys because it is baked into the tools they use.
A notable example is acme.sh, which defaults to reusing the same private key for new certificates, making it challenging for developers to avoid key reuse without explicit configuration changes.
In fact, the command line flag required to use a new private key is super long (and I doubt anyone would remember it).
And this behavior likely won't change, given the maintainer's view on deleting or overwriting existing private files.
This convenience comes at the cost of security, and without awareness, developers can inadvertently expose their systems to vulnerabilities.
Real-World Examples of Key Reuse
Here are a couple eye-opening anecdotes that illustrate just how widespread the issue is:
Verizon: Verizon is a big company with a big security budget. Verizon reused the same private key for over 11 years across 113 different domains!
They revoked one of the certificates back in 2020, but didn’t specify a reason. They continued to use the same private key for two more years.
Public Software Provider: A large, publicly-traded software company has been reusing the same private key for a bunch of different client deployments since 2014. Their client list includes major organizations such as NASA and major financial institutions, among others.
Earlier this year, their private key was compromised. In response, they revoked six different client certificates. But they missed 12 of their other clients’ certificates!
To make matters worse, after the key compromise, they issued another 7 TLS certificates for seven different organizations!
This example highlights the challenge of remediating an exposed private key when it’s reused so widely.
These are just a few examples of how easily private key reuse can become a critical security issue—especially if an attacker compromises a key and organizations fail to respond appropriately.
SSH Key Re-use: A Hidden Security Challenge for GitHub Users
After going down the TLS rabbit hole, we brainstormed other places where users might reuse the same private key. GitHub was an obvious contender.
We reviewed 65 million active GitHub user account keys and found 2% reuse SSH keys across multiple accounts!
Developers often reuse the same SSH key across personal and corporate GitHub accounts out of convenience. However, this practice creates significant security risks. If an attacker gains access to a single private key, they can potentially access all repositories linked to that key, spanning multiple projects and even organizations.
Fall 2024 Update
Since conducting the research, GitHub started blocking users from reusing the same private key across multiple accounts.
Bravo GitHub!
What you can do
First, we recommend checking your current TLS certificates for private key reuse. We open-sourced our internal tool as well as launched a hosted version on Truffle Security’s website to help.
To use the hosted tool, upload a TLS certificate or PEM file and click "Submit."
This will kick off a SQL query against crt.sh’s public postgres database containing the Certificate Transparency logs.
Here’s a short video showing how to use the hosted tool (no audio):
The command line tool is nearly identical, except that it also accepts domains as input.
In those cases, it’ll use openssl
to programmatically query the current TLS certificate associated with that domain and then return all certificates that use the same private key.
Note: If you find more than two results, don't panic. Certificate Transparency logs (ie: where this data comes from) often record two entries for the same TLS certificate. Technically, these are called precertificates and leaf certificates.
Second, we recommend reviewing the command line arguments your organization uses with any ACME protocol frameworks (like Certbot, Acme.sh, etc) and compare them to the documentation to ensure you’re not reusing private keys.
Finally, if all you have access to is a private key and you’re not sure which domain or GitHub account it’s associated with, run TruffleHog against it.
TruffleHog will identify which SSH accounts on GitHub a specific private key can access, as well as determine which TLS certificates a given private key can encrypt for.
Conclusion
Private key reuse across TLS certificates and SSH keys might seem like a minor oversight, but it poses a similar security risk as reused passwords. If you’re curious about key reuse in your organization, we recommend the following two steps:
Check your existing TLS certificates to see if that private key is associated with any other certificates. You can use our hosted tool or run it locally.
If you use ACME tools for short-lived certificate issuance, check your command line arguments and read the documentation to determine whether you’re reusing private keys.