The Android network-security-config and OKHttp Client is support Public Key Pinning like.
<network-security-config>
<domain-config>
<domain includeSubdomains="true">my_domain.com</domain>
<pin-set expiration="2018-01-01">
<pin digest="SHA-256">7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin>
</pin-set>
</domain-config>
</network-security-config>
CertificatePinner certificatePinner = new CertificatePinner.Builder()
.add("my_domain", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
.build();
However, in my case, I will need to pin the Certificate file (even it can expired), instead of Public Key. Because Certificate file is more secure and iOS is pinning Certificate file with ServerTrustPolicy.pinCertificates(...).
I haven't found any built-in methods to support Certificate file pin that can check the expiration. What I tried is
- Use
trust-anchorswith my domain certificate
<network-security-config>
<domain-config>
<domain includeSubdomains="true">my_domain.com</domain>
<trust-anchors>
<certificates src="@raw/myDomainCA"/>
</trust-anchors>
</domain-config>
</network-security-config>
This way work but I can not have any fallback for the expiration
- Use
HandshakeCertificates
val certificates = HandshakeCertificates.Builder()
.addTrustedCertificate(myDomainCA)
.build()
val client = OkHttpClient.Builder()
.sslSocketFactory(certificates.sslSocketFactory(), certificates.trustManager)
.build()
With this way, I can handle my domain's certificate expiration, but I can't connect to other servers. I want to pin certificate only for my domain, without adding certificates for all the other servers I use. Moreover, if I add addPlatformTrustedCertificates(), then the certificate pinning for my domain does not work.
Is there any other approach to pin certificate file in Android?