1

I am attempting to implement certificate pinning across a suite of mobile apps.

I have been reading a lot about the different strategies (pinning to the CA/intermediate, pinning to a leaf cert, providing multiple cert options on the client due to expiry).

In order to fully understand our best approach for the front and backend, I need to understand how pinning to any certificate really makes a difference to a savvy hacker - if all we're doing is checking against a given certificate on the client, and an attacker can very easily obtain a copy of our certificate, what do we really gain from pinning?

mag725
  • 113
  • 1
  • 4

2 Answers2

12

The power in a certificate is NOT in the certificate. It is in the private key. When a server "uses a certificate", it really uses the private key; and the server shows the certificate (that contains only the public key) to the client. The certificate is a proof that a given public key belongs to a specifically named entity. For instance, the certificate that is used by the SSL server www.google.com contains that name (www.google.com) and Google's public key. Google won't show you their private key, of course !

A certificate is not accepted as proof merely because it exists; a client is supposed to perform certificate validation, a complex and convoluted process which entails building certificate chains and verifying a lot of signatures, because a certificate is signed by an authority that is endowed with the power to sign certificate, and is therefore named a certification authority (or CA for short).

Certificates are described in X.509, which is best described as "the Devil's Masterpiece Of Confusion". To practically cope with the sheer complexity of X.509, implementations, in particular Web browsers and other SSL client applications, tend to "take shortcuts" which allow the whole validation thing to complete within reasonable time, but also have a deleterious effect on overall security.

Certificate pinning is a method by which some implementations try to restore a bit of security while still being practical. All of X.509 is context-free: a client is supposed to be able to validate a server certificate without any memory or state kept from previous validations. Certificate pinning is the negation of that notion: the client "pins" a certificate by remembering that a given certificate was used by some server, and then using that information to efficiently "validate" that certificate, should the client connect again to the same server. Pinning even goes to reject a server certificate if it is not the same as the one used by the server during a previous connection to that same server.

The idea is that if an attacker tries to show you a fake server, he won't be able to show the certificate of the genuine server -- of course, the attacker could show a copy of the true certificate (that's public data, the server sends it to all connecting clients), but the attacker would not be able to use the corresponding private key, since he does not have it (the private key, as the name says, is private). Instead, in order to be able to pose as a fake server that can do a complete SSL handshake, the attacker must feed the client a fake certificate that contains the attacker's public key, distinct from that of the server. With certificate pinning, the suspicious client will notice that the server apparently switched certificates, and will find that fishy, and will complain to the user, who will then click off the friggin' warning popup and proceed to sending his credit card number to the attacker because users are like that.

It shall be noted that certificate pinning does any good only in cases where the attacker could obtain a certificate that is accepted by what passes for certificate validation code in client applications. There have been a few highly publicized cases of a CA being bribed or hacked into issuing fake certificates; however, this is still rare. Also, certificate pinning cannot be really absolute because certificates have validity dates, for a bunch of reasons (some of them being even rationally acceptable), so there must be some situations where a client with certificate pinning will still accept that the server changed its certificate.

An example of protocol, similar to SSL, and using public/private key pairs (not X.509 certificates, though) in a "full pinning" model, is SSH. When you connect to a SSH server for the first time, the client asks confirmation about whether the public key sent by the server is the right one (the human user is supposed to check the hash of that key with some authoritative source); then, the client remembers that key (in the .ssh/known_hosts file for Unix-based SSH clients) and will scream loudly if the server ever happens to change its key.

Tom Leek
  • 170,038
  • 29
  • 342
  • 480
1

I think that there is a misunderstanding of what pinning is. Pinning means that once you've trusted the certificate, you pin it for future use. However, the certificate does not itself provide authentication. Authentication consists of validation of a certificate (using a certificate chain for X509) + verification that the other party holds the private key.

Although certificate pinning may shortcut the certificate validation, it doesn't remove the verification that the other party holds the private key. Obtaining a copy of a public certificate in itself is useless.

Maarten Bodewes
  • 4,602
  • 15
  • 29
  • Just adding some detail... the other party proves they have the matching private key by encrypting something with it that can be decrypted by the public key in the validated cert. – Neil Smithline Apr 23 '15 at 17:42
  • @NeilSmithline The reason I left it out is that it could be *decryption* or *signature generation* (and actually that seems to be the general direction of TLS for instance). Heck it could be key agreement as well for static (EC)DH keys. – Maarten Bodewes Apr 23 '15 at 17:49