How to make it work Certificate pinning (HPKP) and self signed certificate in a local network?

I need to use SSL in a local network and I want to avoid browser invalid certificate error.

My idea is to generate self signed certificate and then use Certificate Pinning (HPKP) so to tell browser only this certificate can be trusted?

I currently explore all options related to this idea. I have tested with a self signed certificate and HPKP header (Public-Key-Pins) with value, like:

"pin-sha256="somedataencodedbase64=";pin-max-age=10;includeSubDomains"

Browser does not accept it as a secure. I still need to finish this test (with different self signed certificate and I need to make sure that SPKI is calculated properly ...

Now questions are:

  • Are self signed certificate issued for given local host name (e.g. mylocalserver) and pinned in server response even valid? Will this even work?

  • Does certificate pinning work for a local host names (this would mean, it only works with domain names)?

  • Does pinned certificate have to firstly valid or thrusted by CA (this would mean self signed certificates can not be pinned - unless they are added to Trust Store on a client)?

  • What would be the simplest another way to have a valid SSL locally, so I do not need to configure client (client Trust Store)?

  • Can we seen certificate pinning as alternative of trusted CA? I read somewhere it is just additionally so this means certificate chain need to be valid first, then you can pin it?

  • I also think more and more if this idea will even work. Because then we would see more use of this technique. Everyone would generate self signed certificate and just pin it ... And save few bucks on a CA trusted certificate ... Or what I am getting wrong or right about the whole concept?


Solution 1:

HPKP does not replace the normal validation. Instead it is additionally to the normal validation. Thus, if the normal validation fails since the certificate is self-signed HPKP will not help.

Solution 2:

Are self signed certificate issued for given local host name (e.g. mylocalserver) and pinned in server response even valid? Will this even work?

Yes, HPKP simply advertises a signature for a given x.509 certificate. Browser (or any web-client) just caches it for the period stated, and then it verifies this signature during further visits.

Does certificate pinning work for a local host names (this would mean, it only works with domain names)?

Local host name is a host name, like any other. Even if it's short. Even if it's has a local TLD. The thing is - how your client resolves it and what it requests in the Host: header of the HTTP request. If it resolves a host foobar to a proper IP and then asks this Host: in the HTTP request, and the self-signed certificate has it's CN set to foobar, then the whole scheme starts to work.

Does pinned certificate have to firstly valid or thrusted by CA (this would mean self signed certificates can not be pinned - unless they are added to Trust Store on a client)?

No, they do not. However, somehow your web-client should have a way to trust the server certificate. Either it's put in the list of the trusted server certificates, either you create an exceptions (this is actually the same as previous), either you create local CA and sign the server certificate with you local CA certificate. Self-signed server certificate is just a way to skip the local CA creation. By the way, all the official CA use the self-signed certtificate as the root point of their public-key infrastructure. That is the legitimate way of creating the CA. An official CA is merely a CA who's certificate is added to the truststore of the most known software, like OSes, browsers, and so on. Negotiating the addition costs money, that's why most of them aren't free.

What would be the simplest another way to have a valid SSL locally, so I do not need to configure client (client Trust Store)?

Getting a self-signed certificate for every service you have. If you have only few such services, you deal with self-signed certificates, if you have dozens, you create your local CA. There's also a legitimate free way to get publicly accepted X.509 certificates - just use the LetsEncrypt certificate authority - it's free. However, they don't provide wildcard certificates - the ones with a *, and this can be a problem if you have a huge number of services.

Can we seen certificate pinning as alternative of trusted CA? I read somewhere it is just additionally so this means certificate chain need to be valid first, then you can pin it?

Nope. Certificate pinning is the countermeasure for man-in-the-middle attacks, when someone impersonates the target CA. For this that "someone" must already put his root CA certificate into your truststore, but that's another problem.

I also think more and more if this idea will even work. Because then we would see more use of this technique. Everyone would generate self signed certificate and just pin it ... And save few bucks on a CA trusted certificate ... Or what I am getting wrong or right about the whole concept?

You definitely are.

Solution 3:

After further research, as I really wanted to dig down to the actual specification.

So RFC 7469 says:

2.3.1. Public-Key-Pins Response Header Field Processing

If the UA receives, over a secure transport, an HTTP response that includes a PKP header field conforming to the grammar specified in Section 2.1, and there are no underlying secure transport errors or warnings ...

So now officially is clear that first a proper SSL handshake needs to happen (including validation of the certification chain) and then HPKP can happen ...