public final class CertificatePinner extends Object
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.
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.
Wildcard pattern rules:
*
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.com
is permitted, while *a.example.com
,
a*.example.com
, a*b.example.com
, a.*.example.com
are not permitted.
*
cannot match across domain name labels.
For example, *.example.com
matches test.example.com
but does not match sub.test.example.com
.
*.example.com
pinned
with pin1
and a.example.com
pinned with pin2
,
to check a.example.com
both pin1
and pin2
will be used.
CertificatePinner
can not be used to pin self-signed certificate
if such certificate is not accepted by TrustManager
.Modifier and Type | Class and Description |
---|---|
static class |
CertificatePinner.Builder
Builds a configured certificate pinner.
|
Modifier and Type | Field and Description |
---|---|
static CertificatePinner |
DEFAULT |
Modifier and Type | Method and Description |
---|---|
void |
check(String hostname,
Certificate... peerCertificates)
Deprecated.
replaced with
check(String, List) . |
void |
check(String hostname,
List<Certificate> peerCertificates)
Confirms that at least one of the certificates pinned for
hostname
is in peerCertificates . |
static String |
pin(Certificate certificate)
Returns the SHA-1 of
certificate 's public key. |
public static final CertificatePinner DEFAULT
public void check(String hostname, List<Certificate> peerCertificates) throws SSLPeerUnverifiedException
hostname
is in peerCertificates
. Does nothing if there are no certificates
pinned for hostname
. OkHttp calls this after a successful TLS
handshake, but before the connection is used.SSLPeerUnverifiedException
- if peerCertificates
don't match
the certificates pinned for hostname
.public void check(String hostname, Certificate... peerCertificates) throws SSLPeerUnverifiedException
check(String, List)
.SSLPeerUnverifiedException
public static String pin(Certificate certificate)
certificate
's public key. This uses the
mechanism Moxie Marlinspike describes in Android Pinning.Copyright © 2016. All Rights Reserved.