HPKP Messed up | Need Advice and Help

Hi, I’m experimenting with Public Key Pinning (HPKP).
So when I renewed the certificate, HPKP was affected. At this point I’m not sure how to PIN in a way that will never mess up the HPKP whenever there’s a certificate renewal.

Assuming that the website is now not accessible anymore because of the keys in the HPKP having changed during the renewal - in other words a bricked website now.
So I have two questions:

  1. How can I bypass the mess HPKP did, that is, not giving access to the website.
    Will a certificate revocation nullify that?

  2. Anyone has a clear guide of how to achieve correct way of doing pinning (HPKP) which will not get messed up whenever there’s a certificate renewal?


You can’t unwind the effect of pinning. If you could then bad guys would also be able to do the same and pinning would be useless.

Revoking your certificate won’t help as it just tells anyone who asks that this certificate isn’t trustworthy after all. If you explain in detail what you did people might have suggestions but it is very possible you’ve bricked it and now it’ll be useless for several months.

Hi, thanks for the reply.

I did the pinning on the first-time-issued certificate.
When I renewed the certificate and the pinning was now wrong Letsencrypt has generated new keys

Do you have the old, pinned key? Then you can use this key, to make a new certificate.

hi @7php

First of all review the various things you can pin in the HPKP here: https://scotthelme.co.uk/guidance-on-setting-up-hpkp/

Reusing the old key is an option

You should also have had to pin a backup key which you can use to generate a CSR and obtain a new certificate

Which client did you use?


1 Like

hi @ahaw021
thank you for the response.

Yes I do have all my keys, I keep a version of all of them.

The link you provided is a very good pointer. I’m surprised I have not landed on that page despite reader some of Scott’s posts. So thank you very much for this.

One doubt that I have is, how to I generate a certificate with letsencrypt by providing it with a CSR? I do things commandline and not if there’s a param to give it a csr. Do you have a link to such an article?

Thank you very much @ahaw021

absolutely :smiley:

certbot certonly --manual --csr xx --preferred-challenges “dns”

I am not sure if certonly can be used with other plugins (such as apache) as I usually use it with --manual

Manual can complete either HTTP-01 or DNS challenge

–csr CSR Path to a Certificate Signing Request (CSR) in DER or
PEM format. Currently --csr only works with the
’certonly’ subcommand. (default: None)

I think HPKP is one of those ones that needs a bit of thinking (e.g. the client should create the staples and keep the backup keys)

I am writing a few things to contribute :smiley:


1 Like

had a bit of a read

I believe you should be able to use the apache or nginx authenticator with certonly but you may need to take extra steps to install (if your server is not currently pointing to etc/live/directory)

Authenticators are plugins used with the certonly command to obtain a cert. The authenticator validates that you control the domain(s) you are requesting a cert for, obtains a cert for the specified domain(s), and places the cert in the /etc/letsencrypt directory on your machine. The authenticator does not install the cert (it does not edit any of your server’s configuration files to serve the obtained certificate). If you specify multiple domains to authenticate, they will all be listed in a single certificate. To obtain multiple separate certificates you will need to run Certbot multiple times.

@schoen am i on the right train of thought?


wow, thank you so much for the energy & effort to help! awesome !
Yes I’m using certbot, cool.

hey @ahaw021
I have used certbot as you mentioned above to generate a new certificate based on my backup key.
It generated three files:

  • 0000_cert.pem
  • 0000_chain.pem
  • 0001_chain.pem

I have made all the changes, including the PINNING.
I think this 10th time getting my head into this HPKP, I think I could probably have gotten this in my mind straight now. Asking a friend to verify if he can access the website now, which we have set into an “experiment” to understand this HPKP thing.

A question for you @ahaw021:

  • Since I have manually generated this certificate. Next time when it expired, should I manually generate a new one or ask certbot to renew it? If with certbot renew, what’s the command to use?

@ahaw021, you Sir, deserve a BIG KUDOS for your awesome response and pointers which have helped me understand/consolidate certain things in my mind. CHEERS

1 Like

@7php, I’m glad that you were able to get things fixed with @ahaw021’s help.

There is a feature that I’m working on (but have been slow to finish) that will re-use the previous key when renewing a certificate in Certbot, if you specify the appropriate option. Currently this can never be done by certbot renew, which always generates a new key every time. One of the main reasons that some users would like the ability to re-use a previous key is indeed for HPKP. So, we know that Certbot could be more helpful in this regard.

Notably, when you use a CSR, the certificate that you get cannot be renewed by certbot renew (you need to use the CSR again and run the same command again to obtain a new version of that certificate).

1 Like

Hi @schoen thank you for all the awesome effort Certbot and all you do for all of us and LEtsEncrypt community.
Appreciate the info that you gave.

So to confirm, I will need to regenerate a new certificate, but I can use same CSR as follows:
certbot certonly --manual --csr previous_csr_file --preferred-challenges "dns"

  1. You confirm?

  2. This would also mean that it will resolve the HPKP issue of not having to change the PINS - am I correct?

That looks right to me, although I haven’t done this exact operation in this form. Maybe you can let us know the results.

--csr in Certbot is a way of specifying an existing CSR, not a way of creating a new one.

Guys to be clear, the following command below has already worked for me in helping me fix things.

certbot certonly --manual --csr csr_file.csr --preferred-challenges “dns”

The above command I confirm works, @schoen.
STEPS that I did:

  1. I had my private key (the backup key in my previous HPKP chain of PINS)
  2. I used that private key to generate a CSR file
  3. I finally used that CSR file with the above certbot command to generate my LE certificate.
  4. I then simply instruct my server to use that certificate, along with the private key.

So you can definitely see this as “instead of renewing my expired certificate”, I generated a new one with the same CSR.


When you renew an expired certificate, you are also getting a new one with the same subject names. :slight_smile: (Though in current practice, normally not the same key.) However, Certbot will save it in the same place as the old certificate, which may hide the fact that it is actually a new certificate.

@schoen thank you for this info

A question in general:
Why does renewal of a certificate need to change the Key and not keep “the same old data, same key, initial creation date”, but with just an update on the expiry?

They private key can remain the same.
The public cert (key) will have to be new as the expiration has changed.
Understand that the public cert is cryptographically signed/encrypted - it can’t be modified.
If it could be so easily modified, we would not have much trust in this system.
I.E. What would stop anyone from just changing the expiration date?
Keeping the original creation date is also misrepresenting the facts; as that new cert was just issued (not issued previously).

1 Like

thank you @rg305 for the explanation.

Right, the change to the key is just the default behavior of Certbot (which I need to finish the change to let people opt out of).

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.