1
$\begingroup$

I am reading a networking book by Mike Meyers, and it says that a certificate is a file that contains

  1. A public key, and
  2. A signature (cryptographic hash of the public key, encrypted with the private key).

I can understand that the signature helps ensure that the public key was not tampered with. If I make a request to a secure site and get a certificate, then I get a public key and a signature all in one certificate file. To verify that the certificate arrived intact, I decrypt the signature with the public key (hash #1), hash the public key from scratch myself (hash #2), and agree that hash #1 equals hash #2.

But does that actually do any good? A man-in-the-middle attack can just intercept the certificate, replace it with their own intact certificate, and I won't know the difference. Checking the hashes seems futile because the certificate could have been signed by the private key of the perpetrator, not the one from the site I requested.

Apparently certificate authorities address this vulnerability, but I don't see how an extra signature in the certificate file would help. Is it signed by the CA's own private key? And what is the guarantee exactly? If the first round of hash-checking doesn't preclude a man-in-the-middle attack, how will another signature help?

$\endgroup$
6
  • 3
    $\begingroup$ You are checking if the certificate is signed by a Trusted CA. Your trust store contains the Certificates (i.e. Public Keys) of all CAs you trust. You use the public key in your trust store to verify the certificate you are getting from the secure site you want to visit. You do not use the public key sent by the cert to verify this $\endgroup$
    – user93353
    Commented Nov 3, 2022 at 0:29
  • $\begingroup$ Ah, so the CA’s certificate decrypts the CA’s signature of the site’s certificate? Assuming I got the CA certificate securely and the perpetrator doesn’t have it, I now understand how that ensures the integrity of the site’s certificate. Still, there is the issue of securely obtaining the CA’s certificate in the first place. Also, wouldn’t I have to assume that the perpetrator does not also have the CA’s public key? Is this an edge case in public key cryptography where the public key needs to be private? $\endgroup$
    – landau
    Commented Nov 3, 2022 at 9:30
  • 1
    $\begingroup$ Perpetrator will also have the CA's certificate & hence the CA's public key. A certificate is not a secret because it contains only the public key and nothing secret like the Private key. You can use the public key of the CA's certificate to verify the signature of the site's certificate & verifies that the site's cert has indeed been signed by that CA. In your trust store, you keep only certs of CAs you trust. $\endgroup$
    – user93353
    Commented Nov 3, 2022 at 9:53
  • 1
    $\begingroup$ You own the trust store of your browser. It's your responsibility to make sure the correct certs of CAs you trust are in your truststore. Your browser verifies the site cert using the Certs in your browser's trust store. It just looks up the name of the CA from the site cert but then finds that CAs cert from your trust store. If someone was able to place a spurious cert of a trusted CA in your truststore or was able to place the cert of some CA you don't trust in your trust store, then in either case all bets are off. $\endgroup$
    – user93353
    Commented Nov 3, 2022 at 10:11
  • 1
    $\begingroup$ Terminology issues: in it's general definition, a signature is not "a hash of (what's signed) encrypted with the private key". And for it's verification one does not "decrypt the signature with the public key". That does not even hold for RSA. Independently: "the private key" of 2 is in general not matching the "public key" of 1. When they form a key pair, the certificate is a self-signed certificate (rather than an authority-signed certificate), or is a (Certificate) Signing Request (rather than an actual certificate). $\endgroup$
    – fgrieu
    Commented Nov 3, 2022 at 11:37

2 Answers 2

5
$\begingroup$

I can understand that the signature helps ensure that the public key was not tampered with.

The certificate contains a lot of other information, which is all signed by the signature. An X.509 certificate consists mainly of a part called TBSCertificate, which literally means "to be signed certificate". The only parts that are not included are is the initial ASN.1 SEQUENCE and - of course - the signature itself.

A successful signature verification does indeed show that none of the information is tampered with. However, more importantly, it also shows that the information in the certificate was deemed correct by the issuer of the certificate. This is what enables a public key infrastructure (PKI).

If I make a request to a secure site and get a certificate, then I get a public key and a signature all in one certificate file.

You'll normally get a certificate chain that hopefully leads up to a trust anchor. As indicated before, certificates contain much more information than just a public key and a signature. Finally, the data received is usually just handled in memory; it may be stored in a file or cached, but there is no need for it to be in a file.

To verify that the certificate arrived intact, I decrypt the signature with the public key (hash #1), hash the public key from scratch myself (hash #2), and agree that hash #1 equals hash #2.

As indicated, the part that you has is the "to be signed" part which includes the public key. Furthermore, signature verification is not the same as decryption with the public key and then performing a hash compare.

But does that actually do any good? A man-in-the-middle attack can just intercept the certificate, replace it with their own intact certificate, and I won't know the difference.

The idea is that you build a trust path from the received certificate chain up to a trust anchor. Then you verify and validate each certificate in the chain. If both the verification and validation succeeds then and only then can you trust the server certificate.

Creating the trust path and the validation of the certificates is usually much harder than verifying the signatures.

Validation consists for instance of:

  • checking if the certificate is still in the validity period;
  • checking if the certificate has not been revoked by the CA (i.e. checking the status using a CRL or OCSP);
  • checking if the right data elements are present, such as serial number, the right policies, the correct (extended) key usuages.

For web servers it is also of vital importance that the name of the server is presented in the certificate (commonly in the Subject Alternative Name or SAN for short). If the server name is not checked then the certificate basically has no value: valid any server / private key combination can be used to authenticate (e.g. anyone with a valid certificate for their own site could impersonate Google).

Checking the hashes seems futile because the certificate could have been signed by the private key of the perpetrator, not the one from the site I requested.

Yes, but the perpetrator should not have a certificate and private key that can be used to build the trust path. As long as this is not the case the trust path creation or verification should fail.

Apparently certificate authorities address this vulnerability, but I don't see how an extra signature in the certificate file would help.

It's not an extra signature, it is the signature. There is only one certificate authority that issues the certificate. A PKI infrastructure is a tree structure, usually with a trusted, self-signed root certificate at the top.

Is it signed by the CA's own private key?

Yes, correct.

And what is the guarantee exactly?

Good question. The guarantee is that the receiver is that all entities in the domain should be able to build a trust path to a trust anchor. For this kind of PKI this is usually a collection of root certificates delivered - for instance - with your browser or operating system. The list is kept up to date using updates of the software.

Furthermore, the CA promises using their signature that the information within the certificate is valid. The check if the information in the certificate request is valid is performed by a sub-entity of the CA called a registration authority (RA). The final certificate consists of information from the certification request (including the public key and server name) and information added by the CA (such as the validity period, an URL to the certificate revocation list etc.).

For certificates used for TLS / HTTPS the CA should also test that the entity that performs the request owns or at least controls the server.

If the first round of hash-checking doesn't preclude a man-in-the-middle attack, how will another signature help?

Reiterated: it's called signature verification (which includes the hashing part) and there is only one signature. The TL;DR is that building and validating the trust path will preclude man-in-the-middle attacks.

Once the client has a trusted server certificate the server still needs to show that it has access to the private key by performing a private key calculation over known data, e.g. the session data in the case of TLS.


One big critique of the PKI used by browsers is that there are a lot of root certificates / trust anchors. Only one of those needs to be compromised for the system to fail. Famously the Irianian government used wrongly issued certificates obtained from a now defunct CA (DigiNotar) to perform a man-in-the-middle attacks for Google services.

For proprietary communication it makes sense to only install trust anchors for specific CA's.

$\endgroup$
1
  • $\begingroup$ Sorry, I need to perform some other duties, will be back to include links to e.g. X509 certificate path validation and highlight the terms taken from the X509 standard. $\endgroup$
    – Maarten Bodewes
    Commented Nov 3, 2022 at 11:52
2
$\begingroup$

You start with a root CA certificate, say from the certificate authority Let's Encrypt. The self-signature on the root CA certificate isn't important; what's important is the public key—you can use it to verify signatures by Let's Encrypt.

When you go to https://crypto.stackexchange.com/ in your browser and it makes a TLS session, the server at crypto.stackexchange.com gives you two things:

  1. A server certificate.* The certificate is a fancy string of bits that essentially says:

    The owner of the domain names *.stackexchange.com (and stackoverflow.com and askubuntu.com and serverfault.com and …) has authorized the bearer of the private key for the RSA-2048 public key with exponent e=65537 and modulus n=D7:77:79:2A:EC:… to serve HTTPS at those sites.

    —Sincerely, Let's Encrypt

  2. A proof that the server in the TLS session knows the private key for the RSA-2048 public key with exponent e=65537 and modulus n=D7:77:79:2A:EC:….

You can use the Let's Encrypt public key to verify the signature on the statement in the server certificate (1).

You then can use the public key in the server certificate (1) to verify the proof (2).

Then you can be confident that, according to Let's Encrypt, the server is authorized to serve the web site https://crypto.stackexchange.com/.

If you already have the Let's Encrypt public key, a MITM can't forge a signature on a fraudulent server certificate, with a public key the MITM knows the private key of, that will pass verification with the Let's Encrypt public key.

How do you get the root CA certificate, like Let's Encrypt's? This is typically bundled in the software installed on your computer, and updated with the same software updates you use to update your operating system or browser. Of course, there's a chicken/egg problem (how do you verify the original software?), but it's limited in scope—you don't have to have the certificate of every web site on the planet bundled in your operating system or browser, just a few root CA certificates.

To verify that the certificate arrived intact, I decrypt the signature with the public key (hash #1), hash the public key from scratch myself (hash #2), and agree that hash #1 equals hash #2.

Note: There is no encryption involved in the certificate, just signature and verification. A public-key signature scheme is a way to make signatures with a private key, and to verify signatures with the corresponding public key—there is no inherent connection to public-key encryption and decryption operations.

It is a common misconception, arising from some similarities in the core of RSA-based signature and encryption schemes, that verifying a signature involves decryption; describing signature verification as "decryption with public key" is a telltale sign of a bad source of information about cryptography.

(TLS involves encryption, of course, and older versions of TLS used public-key encryption to establish a session key and furnish the proof (2), but it's not involved in the certificate verification process.)


* There might even be a chain of certificates—not just the root CA certificate and the web site certificate, but intermediate CA certificates as well, with formal rules written down in the intermediate CA certificate on what they are allowed to certify, and expiration dates, and so on and so forth.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.