diefferson / http_certificate_pinning

Https Certificate pinning for Flutter
Apache License 2.0
84 stars 76 forks source link

Add support for pinning public key of Root certificate only #54

Open edocabhi opened 1 year ago

edocabhi commented 1 year ago

With the addition of public key pinning capability, one would be able to use the public key from the certificate instead of the hash from the certificate file. This will enable the certificate provider to renew the certificate with same public key and there would be no potential down time for the app.

edocabhi commented 1 year ago

@diefferson Do you think we can incorporate this feature? Also, is there any work in progress already? If not I would try to implement this.

diefferson commented 11 months ago

Hey @edocabhi , we already use the public cert to make the validation, but is used the hash from certs and this is a pattern followed for the community.

For certifications renews there are some strategies, the most common is to have two certificates with different expire times, one is the current in the server and the other is the next certificate that will be used, and you can pin both on app, so when the server changes the certificate the app still working and you have some months to update the app pinning the next certificate.

lukehutch commented 9 months ago

For certifications renews there are some strategies, the most common is to have two certificates with different expire times, one is the current in the server and the other is the next certificate that will be used, and you can pin both on app, so when the server changes the certificate the app still working and you have some months to update the app pinning the next certificate.

@diefferson is there no way to cryptographically negotiate for the verification of an updated certificate with the server?

For example, set up a one-time pad between client and server (e.g. by installing a server's public key in the app at time of distribution), then have the server encrypt its current SHA fingerprint using the server's private key, before sending it over TLS. Then if the client's view of the server certificate doesn't match the encrypted certificate, the connection would fail. This should prevent MiTM proxies from working, at least...

edocabhi commented 8 months ago

@diefferson I see that you are suggesting to have two certificates but it's not always possible to get a second certificate that is guaranteed to be used in the future with the server. Also, for security reasons, many teams wouldn't produce a certificate years in advance, to be used in the future.

edocabhi commented 8 months ago

@lukehutch I am suggesting something similar to what you have mentioned.

Here is how it looks like

The difference is that the current implementation takes the entire certificate chain to create the hash. So, if one of the certificate changes in the chain then the TLS handshake will fail.

@diefferson If you think we can include this as another option alongside the existing one then I would be happy to create a PR for it. I already have this working on my end. If not then we can close this ticket.

lukehutch commented 8 months ago

@edocabhi So what you're saying is that the root certificate should last much longer than the server certificate, and the root certificate can be used to create a series of server certificates?

Either way, as of 2020-09-01, TLS certificates are not valid for more than 13 months...

So what happens if a user doesn't use an app for 13+ months (or 26+ months), then tries to use it again? Certificate rotation will break this way.

What I am looking for is a way to check certificates that proves whether or not there is a MiTM proxy, and does it without having to rotate keys by checking in at least once or twice every 13 months. For example, the server encrypts its key signature, and the app decrypts it and compares the server-provided certificate signature to the signature it obtains via a TLS request.

diefferson commented 8 months ago

Hi guys, I have already taken a look at these solutions that use the public key instead of the certificate, what happens is this lib is based initially on native solutions from the iOS and Android side, and the native code only supported pin the certificate when I have worked on it, do you know if is supported by native libraries now use the public key?

Anyways, I remember that this approach has some problems in case your system uses certificates from a cloud service like Google Cloud, or AWS, or even from providers such Let's Encrypt, on these scenarios the provider public key is the same for the certificates, so is easy to get a certificate with the same public key.

edocabhi commented 8 months ago

@lukehutch Yes, generally the root certificate has a longer expiry time than the intermediate or server certificate. The reason to use a public key of the root certificate is that even if you change the certificate everyday but use the same key to sign the certificate, the handshake will succeed.

edocabhi commented 8 months ago

@diefferson Yes, I checked for native Android and iOS libraries and both platforms natively support pinning of the public key hash. https://developer.apple.com/news/?id=g9ejcf8y https://developer.android.com/privacy-and-security/security-config#CertificatePinning

I understand that if we use a common Root Certificate from a cloud provider as you mentioned, getting hold of the certificate with same public key is possible. However, I have a special use case where organizations have their own Root Certificate which is not available for public use.

Also, the proposal is not to replace existing implementation but have a second method which can be used to pin multiple public key hash if the developer wants to use it.

lukehutch commented 8 months ago

@edocabhi That's exciting. It would be super awesome if you could figure out how to get this all working.

In particular, there would need to be a step-by-step guide explaining what exactly to do, and best practices, with a full explanation of the ramifications of different choices, because most documentation about this (including the two that you linked) assumes the reader already has a lot of knowledge in this area. I'm struggling to get my head around some parts of this.