I had to manage a similar situation: I had to implement certificate pinning and I don't want to synchronize app release with certificate expiration.
The solution (is a compromise I know) I implemented works in this way: if certificate app use is still valid, the app applies the certificate pinning. If the certificate is expired, the app does not use certificate pinning. In this way, the app is "exposed with no certificate pinning" between the certificate expiration date and app update (with new certificate hashcode). During this period the app is exposed, but it continues to work!!
The code:
public abstract class CertificatePinnerManager {
private CertificatePinnerManager() {
}
public static final String DATE_FORMAT="dd/MM/yyyy";
public static final String CERTIFICATE_PINNING_END_CHECK = "12/09/2021";
public static final String CERTIFICATE_SHA_256 = "sha256/zzz/yyy/xxxx";
public static CertificatePinner generateCertificatePinner() {
@SuppressLint("SimpleDateFormat") SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
Date strDate = null;
try {
strDate = sdf.parse(CERTIFICATE_PINNING_END_CHECK);
} catch (ParseException e) {
e.printStackTrace();
}
if (new Date().before(strDate)) {
// Certificate pinning enabled
return new CertificatePinner.Builder()
// domain to check
.add("dummy.com", CERTIFICATE_SHA_256)
.build();
} else {
// disable certificate pinning
return new CertificatePinner.Builder().build();
}
}
}
// create okhttp client
OkHttpClient httpClient = new OkHttpClient.Builder()
.certificatePinner(CertificatePinnerManager.generateCertificatePinner())
.build()
I think it would a better solution manage certificate SHA with remote config, but for the moment, this is my solution. :D
I hope it will help you.