Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Understanding Certificate Pinning (littlemaninmyhead.wordpress.com)
49 points by svenfaw on June 15, 2020 | hide | past | favorite | 25 comments


Cert pinning is an anti-pattern. No need for the CA infrastructure if you're going to bypass the CA infrastructure. If you control the software on both sides, which is required for cert pinning, then you can use self-issued certs. Also: roll your certs frequently.

Shameless plug for https://smallstep.com/cli which makes the process of issuing and rolling certs (incl. client certs for mutual TLS) easy enough to be workable in a modern application.


I totally agree: pinning to a single CA is super-fragile and a terrible idea, and if you don't have a need for public certs, doing a proper private PKI (Small-step is a good choice here!) is a good place to go as long as you can run it properly.

However, whether you're running your own or pulling public certs, you should go into any PKI setup assuming you'll need to change out all the certs at some point. If you're going private, make sure you have a mechanism to replace everything--yes, including that private root you just created!--in a safe and secure fashion. Preferably, that would include some manner of doing so that doesn't involve blowing everything up and leaving existing clients high and dry...but that's a business decision to make.

If you're going with public certs, you still have to make that assumption. I see too many developers still pinning trust to a single root CA like Let's Encrypt or GoDaddy and then being stuck when the CA in question is revoked, replaced, expires, or is booted out of public trust, or just because their business insists they use something different. The solution to this is a trust store, which you can make as minimal as you want to: pick two or three public root CAs, stick them in a blob, and tell your app to accept nothing else. That leaves you an out, for the next time the cert industry has a Symantec-like event and everyone has to get off that train right away, since you can move from one of those to another one without having to change anything in the app.


How does using a self-issued cert address the concern of mitm proxying? (specifically, a user intercepting their own traffic to reverse engineer the api/protocol)


You create a Root Self Signed Certificate, and then deploy leaf certs signed by that root to your API.

Then deploy your client apps with the certificate of your self signed root.

Assuming that your root is safe, no attacker will be able to generate a cert that will be accepted by your client.


That doesn't make sense to me, sorry. Got an article or something?


The confusion here might be around the term "self-signed". Technically, all roots are self-signed—that's the definition of a root CA!—but in this case the user just means "self-signed" as in "signed by me, not signed by some commercial third party". "Self-signed certificates", though, usually refer to certificates with no PKI chain: the device created a single certificate, signed it with its own key, and then just distributes it to create trust without the usual hierarchy of a PKI.

The attack on that latter system is that you as the client have no basis on which to trust that cert when its first presented. So an attacker who can intercept that first presentation of the certificate and replace it can MITM the traffic flow without you knowing. Worse, most devs "fix" that initial trust problem by telling the client not to validate the cert when its presented (because they wouldn't have any basis for doing that anyway), so an attacker is free to inject their own cert into the traffic at any time.

Using an actual private PKI hierarchy helps fix this: you create a root, and get your clients to trust only that root. Now you can issue your own certs, and an attacker can't MITM the traffic unless they can get their own cert from your CA. That's the same model as is used with commercial CAs: you're just operating the root of the chain yourself instead of paying someone else to do it.


But isn't this exactly why certificate pinning is needed... Sure I can roll my own PKI and install the Root CA on the client devices, but they can still intercept their own traffic by installing their own trusted Root CA.


If the TLS client isn't a webbrowser, it doesn't have to use the list of trusted roots provided by the underlying system (be it OS or browser).

Certificate Pinning is the solution you'd look to if you have a clients that cannot securely ship with root certificates/cannot pick the root certificates they will use to validate a certificate when initiating a TLS connection.

Edit: I should add that I am not a mobile developer, so I don't actually know if the 'bring your own root CA' method is supported by the corresponding TLS libraries. But I know that this is possible 'in general'


I missed the parenthetical on your comment, my apologies. You're right: if you can monkey around with things enough to SSL-proxy the traffic, then rolling your own PKI will not help prevent that. What will help prevent that, yes, is pinning, but my argument above was that pinning to any single CA (or worse, any single leaf certificate) without a mechanism for replacement is what gets people into trouble. Selecting a small set of trusted CAs is a much stronger pattern, and would preserve the inability of clients to swap out their own certs or proxy their own traffic (although it may also break things—Google had to bend on that one a bit to allow for enterprise SSL decryption, e.g.).


Not entirely accurate. Your client software builds a TLS client with your sole private trusted root. Nobody can MITM with a self signed cert unless they can reverse your client (or system) enough to hook the TLS stack, which there are numerous tools out there to do which is also why (but also irrespective of the fact) IMHO the "zomg we must prevent the user from seeing _their_ traffic" is a totally bogus pursuit. However, if you're dead set on thwarting some subset of the script kiddies, then mTLS is your friend because it's a real solution to the "I want to authenticate my client (perhaps because only it should see the traffic)" problem.


Because you control the client software so you just make a TLS client that has only your root trust anchor. This is exactly the same as CA/pubkey pinning from a threat model perspective.


OpenBSD does something like this. In the current release, they provide the public keys for the next release. After trust-on-first-use it's a never-ending cycle.

I call it trust-on-first-use because I didn't verify the initial signatures. Hmmm..


Don't have an article on hand :/ just something that I've played around over with over time.

Which part is confusing? Maybe I can try to clarify/give examples where helpful.


I think you're maybe talking about an adversarial MITM. I'm talking about someone trying to reverse engineer your API by intercepting their own traffic


>It must be emphasised that if any single CA is breached, then all of TLS breaks. It doesn’t matter what CA you used for your website, it only matters what CA your attacker uses.

How is that possible? If a CA is breached, doesn't that just mean it can create certs impersonating other sites? How does that break all of TLS?


Yes, it's not really helpful for the site to say this breaks "all of TLS" which doesn't itself have any opinion about why you'd trust this or that certificate. TLS per se is unaffected.

But if a CA which is trusted in the Web PKI is "breached" then the nature of that breach determines the consequences for anybody who trusts the Web PKI (which means popular web browsers and a good deal of other software)

* If the breach results in bad guys having the root private key (typically realised as a physical device in a safe) then they can issue any certificate or certificate hierarchy using that key and it would (until you update things not to trust it) work. But this is extremely unlikely, it has probably never happened (it's unclear for Diginotar but appears the root was not actually taken by bad guys, they broke into a bunch of servers they didn't conduct a physical robbery)

* If the bad guys get one or more Intermediate private keys - which are online because they're used in the actual process of minting you a certificate although they're supposed to be protected inside hardware that shouldn't give anybody the keys - they can make any certificates under that intermediate, including further sub-CAs. Unlike a root the intermediate can "just" be revoked, and mechanisms to make that stick in practice exist for all major browsers.

* If the bad guys just break into servers that are responsible for issuance it's trickier. They might be able to cause the Intermediates to sign some certificates but not others depending on what they broke into exactly. For example they may be unable to falsify the date as there's no reason the server they broke into would be allowed to choose the date on a certificate, or they might be obliged to obey rules like CAA checking even if they don't want to because it's done by some other system they can't override. If the owners realise what's happening and turn off the power, the access goes away, the bad guys don't have the keys so they can't make more certificates.

* If the bad guys just broke into some subsidiary system they may only be able to cause issuance / re-issuance of certain specific certificates that system was allowed to cause. e.g. suppose Big Corp contracts with some CA to issue many certificates like springfield.bigcorp.example and smallville.bigcorp.example - there may be authority on file to issue any such certificate until say 2020-08-04, and if bad guys guess that Big Corp's password is "letmein123" they can use that existing authority to make themselves a certificate for fart.bigcorp.example no problem - but that doesn't get them a certificate for news.ycombinator.com or google.com without some other attack.


No, you also need to be able to MITM. Snooping the traffic is not enough to do harm.


Do you keep track of what CA each website you visit is currently using?


It doesn't if the breached CA is removed from your system.


Years ago I read a blog that taught the series of steps needed to perform GNUTLS certificate pinning for Emacs use. At the time, it seemed like a convenient way to boost security. After all, services were only renewing their certificates every 2–3 years, so once you set up your configuration, you wouldn't have to change it for a long time.

But then Lets Encrypt came along and was widely adopted. LE thinks that it is best that certificates expire after only a few weeks. So, if you have pinned a lot of certificates, you start to feel that it is too much work to manage that configuration, you constantly have to update it.


Instead of pinning the cert, you can pin to one or multiple rsa public keys. Then you can use those keys when you generate signing requests (CSR) from lets encrypt.


You shouldn’t be pinning to your leaf certs, which is the only reason LE certs would be a problem here.


Possibly stupid question here (this is not my domain), but what is the alternative to pinning the client to use your leaf certs? If it's pinning to your root cert, then isn't that much more of a pain if/when you need to revoke what the client is using? Or is the correct alternative to pin "to one or multiple rsa public keys" as mentioned in the sibling comment?


Late reply, but: if you really must pin (and you probably shouldn’t), pin to public keys, not the certs in the chain.


Thank you!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: