Certificate Pinning in OKHttp with Certificate file

55 Views Asked by At

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

  1. Use trust-anchors with 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

  1. 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?

0

There are 0 best solutions below