TLDR; either perform certificate creation and app submission within the lifetime of the issued certificate, or; don't use Let's Encrypt, or; don't use pinning in the app and instead apply DANE/DNSSEC and CAA.
Explained:
The normal method for embedded apps (like iOS and Android) that use Certificate pinning is to have multiple pinned Certificates with no (or little) overlapping dates, so the notBefore
of the next valid pinned Certificate is the same as the previous valid pinned Certificate notAfter
date.
By default Let’s Encrypt certificates are intentionally backdated notBefore
by 1 hour from the request. It's up to the CA to decide the notBefore
and notAfter
dates and do not support the methodology used for embedded apps.
Let's encrypt allows you to generate a CSR, which is the best way to customise the Certificate they issue, here is an example from my own production app:
Request Certificate 1:
certbot certonly \
--dry-run \
-n \
--dns-route53 \
--agree-tos \
--csr "<path to my CSR>" \
--register-unsafely-without-email \
--no-eff-email \
--dns-route53-propagation-seconds 300 \
--cert-path "<path to store the issued X.509 Leaf Certificate>" \
--key-path "<path to store the private key>" \
--fullchain-path "<path to store the issued X.509 Leaf Certificate and the chain of intermediate and CA Certificates as a bundle>" \
--chain-path "<path to store the chain of intermediate and CA Certificates as a bundle minus the actual issued X.509 Leaf Certificate>" \
-d sub.domain.tld
Request another Certificate for the same doamin, without removing the original, and run 2 months after the first:
certbot certonly \
--- same as above ---
--duplicate \
--force-renewal \
-d sub.domain.tld
The second certificate is issued with a notBefore
2 months after the first.
Important to note that the CSR format (PKCS#10) doesn't have any fields to put these dates so it's still depending on the Let's Encrypt hidden decisions that you do not control to get this result.
It would be more beneficial for you to go back to your threat model and better understand why certificate pinning was implemented. Mostly pinning is being removed for better suited options, because pinning used to be a solution for many things it was not suited and today we have options like TLSA/DANE, DNSSEC, and using CAA records to completely verify a chain of trust to the expected trust anchor.
If you find that your threat model indicates pinning is the best mitigation for whatever risks you have identified, then you will need to find a CA that can issue Leaf Certificates that are future dated (notBefore
) and have multiple pinned certificates deployed with your app.