Tuesday, December 31, 2019

Android OK HTTP Certificate Pinning Helper



The easiest way to pin a host is turn on pinning with a broken configuration and read the expected configuration when the connection fails. Be sure to do this on a trusted network, and without man-in-the-middle tools like Charles or Fiddler.
For example, to pin https://publicobject.com, start with a broken configuration:

String hostname = "publicobject.com";
     CertificatePinner certificatePinner = new CertificatePinner.Builder()
         .add(hostname, "sha1/AAAAAAAAAAAAAAAAAAAAAAAAAAA=")
         .build();
     OkHttpClient client = new OkHttpClient();
     client.setCertificatePinner(certificatePinner);

     Request request = new Request.Builder()
         .url("https://" + hostname)
         .build();
     client.newCall(request).execute();


As expected, this fails with a certificate pinning exception:
 

 javax.net.ssl.SSLPeerUnverifiedException: Certificate pinning failure!
   Peer certificate chain:
     sha1/DmxUShsZuNiqPQsX2Oi9uv2sCnw=: CN=publicobject.com, OU=PositiveSSL
     sha1/SXxoaOSEzPC6BgGmxAt/EAcsajw=: CN=COMODO RSA Domain Validation Secure Server CA
     sha1/blhOM3W9V/bVQhsWAcLYwPU6n24=: CN=COMODO RSA Certification Authority
     sha1/T5x9IXmcrQ7YuQxXnxoCmeeQ84c=: CN=AddTrust External CA Root
   Pinned certificates for publicobject.com:
     sha1/AAAAAAAAAAAAAAAAAAAAAAAAAAA=
   at com.squareup.okhttp.CertificatePinner.check(CertificatePinner.java)
   at com.squareup.okhttp.Connection.upgradeToTls(Connection.java)
   at com.squareup.okhttp.Connection.connect(Connection.java)
   at com.squareup.okhttp.Connection.connectAndSetOwner(Connection.java)



Follow up by pasting the public key hashes from the exception into the certificate pinner's configuration:
 

     CertificatePinner certificatePinner = new CertificatePinner.Builder()
       .add("publicobject.com", "sha1/DmxUShsZuNiqPQsX2Oi9uv2sCnw=")
       .add("publicobject.com", "sha1/SXxoaOSEzPC6BgGmxAt/EAcsajw=")
       .add("publicobject.com", "sha1/blhOM3W9V/bVQhsWAcLYwPU6n24=")
       .add("publicobject.com", "sha1/T5x9IXmcrQ7YuQxXnxoCmeeQ84c=")
       .build();

Pinning is per-hostname and/or per-wildcard pattern. To pin both publicobject.com and www.publicobject.com, you must configure both hostnames.

Warning: Certificate Pinning is Dangerous!
Pinning certificates limits your server team's abilities to update their TLS certificates. By pinning certificates, you take on additional operational complexity and limit your ability to migrate between certificate authorities. Do not use certificate pinning without the blessing of your server's TLS administrator!


References:
https://square.github.io/okhttp/2.x/okhttp/com/squareup/okhttp/CertificatePinner.html 

No comments:

Post a Comment