Certificate Pinning on Android: OkHttp & Network Security Config
Certificate pinning protects against compromised CAs and man-in-the-middle attacks. Android provides two approaches: Network Security Configuration and OkHttp pinning.
Network Security Config Approach
Create network_security_config.xml:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config>
<domain includeSubdomains="true">example.com</domain>
<pin-set>
<pin digest="SHA-256">
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
</pin>
<pin digest="SHA-256">
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=
</pin>
</pin-set>
</domain-config>
</network-security-config>
Reference in AndroidManifest.xml:
<application android:networkSecurityConfig="@xml/network_security_config">
...
</application>
OkHttp CertificatePinner
val certificatePinner = CertificatePinner.Builder()
.add("example.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
.add("example.com", "sha256/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=")
.build()
val httpClient = OkHttpClient.Builder()
.certificatePinner(certificatePinner)
.build()
val retrofit = Retrofit.Builder()
.baseUrl("https://example.com")
.client(httpClient)
.build()
Getting Certificate Hashes
Obtain hashes from your server certificate:
openssl s_client -connect example.com:443 < /dev/null | openssl x509 -noout -pubkey | openssl pkey -pubin -outform DER | openssl dgst -sha256 -binary | openssl enc -base64
Backup Pins
Always include backup pins from intermediate CAs:
val certificatePinner = CertificatePinner.Builder()
.add("example.com", "sha256/primary=")
.add("example.com", "sha256/backup=")
.add("example.com", "sha256/intermediate=")
.build()
Certificate pinning significantly hardens security. Combine with other practices for defense-in-depth protection.
8 Android app templates available on Gumroad
Top comments (0)