Package com.squareup.okhttp
Class CertificatePinner
- java.lang.Object
-
- com.squareup.okhttp.CertificatePinner
-
public final class CertificatePinner extends Object
Constrains which certificates are trusted. Pinning certificates defends against attacks on certificate authorities. It also prevents connections through man-in-the-middle certificate authorities either known or unknown to the application's user.This class currently pins a certificate's Subject Public Key Info as described on Adam Langley's Weblog. Pins are base-64 SHA-1 hashes, consistent with the format Chromium uses for static certificates. See Chromium's pinsets for hostnames that are pinned in that browser.
Setting up Certificate Pinning
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:
As expected, this fails with a certificate pinning exception:String hostname = "publicobject.com"; CertificatePinner certificatePinner = new CertificatePinner.Builder() .add(hostname, "sha1/BOGUSPIN") .build(); OkHttpClient client = new OkHttpClient(); client.setCertificatePinner(certificatePinner); Request request = new Request.Builder() .url("https://" + hostname) .build(); client.newCall(request).execute();
Follow up by pasting the public key hashes from the exception into the certificate pinner's configuration: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/BOGUSPIN 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)
Pinning is per-hostname and/or per-wildcard pattern. To pin bothCertificatePinner 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();publicobject.comandwww.publicobject.com, you must configure both hostnames.Wildcard pattern rules:
- Asterisk
*is only permitted in the left-most domain name label and must be the only character in that label (i.e., must match the whole left-most label). For example,*.example.comis permitted, while*a.example.com,a*.example.com,a*b.example.com,a.*.example.comare not permitted. - Asterisk
*cannot match across domain name labels. For example,*.example.commatchestest.example.combut does not matchsub.test.example.com. - Wildcard patterns for single-label domain names are not permitted.
*.example.compinned withpin1anda.example.compinned withpin2, to checka.example.combothpin1andpin2will be used.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!Note about self-signed certificates
CertificatePinnercan not be used to pin self-signed certificate if such certificate is not accepted byTrustManager. - Asterisk
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static classCertificatePinner.BuilderBuilds a configured certificate pinner.
-
Field Summary
Fields Modifier and Type Field Description static CertificatePinnerDEFAULT
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Deprecated Methods Modifier and Type Method Description voidcheck(String hostname, Certificate... peerCertificates)Deprecated.replaced withcheck(String, List).voidcheck(String hostname, List<Certificate> peerCertificates)Confirms that at least one of the certificates pinned forhostnameis inpeerCertificates.static Stringpin(Certificate certificate)Returns the SHA-1 ofcertificate's public key.
-
-
-
Field Detail
-
DEFAULT
public static final CertificatePinner DEFAULT
-
-
Method Detail
-
check
public void check(String hostname, List<Certificate> peerCertificates) throws SSLPeerUnverifiedException
Confirms that at least one of the certificates pinned forhostnameis inpeerCertificates. Does nothing if there are no certificates pinned forhostname. OkHttp calls this after a successful TLS handshake, but before the connection is used.- Throws:
SSLPeerUnverifiedException- ifpeerCertificatesdon't match the certificates pinned forhostname.
-
check
public void check(String hostname, Certificate... peerCertificates) throws SSLPeerUnverifiedException
Deprecated.replaced withcheck(String, List).- Throws:
SSLPeerUnverifiedException
-
pin
public static String pin(Certificate certificate)
Returns the SHA-1 ofcertificate's public key. This uses the mechanism Moxie Marlinspike describes in Android Pinning.
-
-