26

I understand what pinning is. I had read about Certificate pinning and I appreciated it's use case. But today I learned pinning can be of two types -

  1. pin the certificate or
  2. pin the public key

Certificate and Public Key Pinning

I would like to understand the use cases for each. Any typical scenarios where we would prefer one over the other?

One doubt I have is: lets say we pinned a public key. Is our connection vulnerable to MitM attacks. Can there be a CA certified root cert that has the same public key as the cert that is used in the client?

Any differences between the two that can help me understand them better are appreciated.

3 Answers 3

20

It really depends on how your application/site manages the certificates and public keys, i.e. how often are the keys and certificates rotated. For example, if your site rotates the certificates very often, then you'll also need to update your application that often as well, if you are pinning the certificate. Whereas, in this use case, pinning public key will be a better idea since the public key associated with the certificate will remain static.

From the OWASP link that you mentioned in the question:

Certificate

The certificate is easiest to pin. You can fetch the certificate out of band for the website, have the IT folks email your company certificate to you, use openssl s_client to retrieve the certificate etc. When the certificate expires, you would update your application. Assuming your application has no bugs or security defects, the application would be updated every year or two. At runtime, you retrieve the website or server's certificate in the callback. Within the callback, you compare the retrieved certificate with the certificate embedded within the program. If the comparison fails, then fail the method or function.

There is a downside to pinning a certificate. If the site rotates its certificate on a regular basis, then your application would need to be updated regularly. For example, Google rotates its certificates, so you will need to update your application about once a month (if it depended on Google services). Even though Google rotates its certificates, the underlying public keys (within the certificate) remain static.

Public Key

Public key pinning is more flexible but a little trickier due to the extra steps necessary to extract the public key from a certificate. As with a certificate, the program checks the extracted public key with its embedded copy of the public key. There are two downsides two public key pinning. First, its harder to work with keys (versus certificates) since you usually must extract the key from the certificate. Extraction is a minor inconvenience in Java and .Net, buts its uncomfortable in Cocoa/CocoaTouch and OpenSSL. Second, the key is static and may violate key rotation policies.

Regarding the MitM, no, your TLS connection will not be vulnerable to any MitM attack as long as you've implemented the certificate pinning correctly. Even if an attacker is able to get a valid certificate for their own domain with the same public key which your application has pinned (through a rouge CA let's say), they still wont have have the corresponding private key. Thus will not be able to create a valid TLS connection with your application (since they will not be able to perform TLS handshake itself).

2
  • Does "pinning the whole certificate" mean the public and private keys are stored in the client application? Or just the public key? This question seems to suggest that you store the public key or the hash/thumbprint of the public key in the client app. It seems odd to suggest the client app keep hold of a copy of the private key, no?
    – cottsak
    Aug 2, 2016 at 2:35
  • 1
    @cottsak: No, the client doesn't need the private key for anything. The private key is not part of the certificate and will never touch the client machine.
    – Tudor
    Nov 9, 2017 at 10:01
4

The big problem with certificate pinning is that certificates have a limited shelf-life and often cost money. Free certificates from lets encrypt only last 90 days. If you pay money you can get just over two years which is the limit set by the CA/Browser forum nowadays. There is no gaurantee this will not be further reduced in future.

You can't pin a certificate until you have bought it and once you have bought it it's lifetime is ticking down whether you use it or not. So if you pin certificates you will likely end up buying many extra certificates and you will likely have problems with people trying to connect using old versions of your code.

On the other hand public keys don't have any kind of lifetime restriction. So if you use key pinning you can generate a keypair, put the private key in your vault and the public key in your app. Then years later you can pull the private key out of your vault, get a certificate and put it into service.

The potential downside of key pinning is that there is no revocation for keys. If your keys are compromised you can revoke the certs but an attacker with a friendly CA could potentially get a new cert with the stolen key. OTOH certificate revocation is pretty fragile in general.

1

Just some of my two cents:

I could imagine that public key pinning be used in scenarios where it can be difficult to update the application in the event that the certificate is renewed (for instance in embedded systems or IoT applications). Otherwise, certificate pinning would be more convenient.

If the public keys are generated with sufficient entropy it would not be likely that there are two keys which are the same.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .