Android Biometrics UX Guide – User Messaging

Users Say: “Biometric…🤷‍♂️🤷‍♀️?”

When I’ve demoed “Biometric” UIs to non-developers, many say:

Why don’t you just say “Fingerprint” or “Face Unlock”?

The reason is that the Biometric APIs have no way to find the type of biometric that will be used.  That’s why we are stuck with using “Biometric” as a catch all.  You can see the terminology being used in Google’s Android Developer Training on Biometric Auth.

We’re also working with the UX / design team on clear iconography/messaging – in the meantime, our suggestion to developers has been to use something along the lines of “Biometric settings”, or “Use biometric”, etc.
– Googler’s Response on Issue Tracker

I have read “BiometricManager” and “BiometricPrompt” enough times to get used to it, but users haven’t.  So let’s see what we can do to create better user messaging.

Option A: Describe “What” Instead of “How”

Say what the user is going to do like “Unlock” or “Login” or “Confirm” or whatever.  Just don’t mention how the user will do it via a biometric.  The system will show the UX for the biometric type anyways in the Biometric Prompt, but your customized wording will be whatever you provide.

 

Consider these scenarios as well:

  • What will you call this on your settings page?
  • What iconography will you use for “Biometric” on a Pixel 4 with Face Unlock? A Fingerprint?  That’s not ideal.
  • How will you encourage your users to use biometrics in your app?  Maybe you could say “Unlock Faster Next Time” and it can be implied that a biometric will be used?

You might be able to get away with this messaging, and if you can, congrats! 🎉

Option B: Write Code and Cross Your Fingers🤞

It’s possible to figure out what biometric will be used the majority of the time, and I’ll show you how. 😎

Running on Pixel 3 Running on Pixel 4

Step 1) See If Device Has Biometric Support

Ask the BiometricManager if it canAuthenticate(), and if it’s successful, or says the user has not enrolled their biometrics, then you know the device is capable.

val biometricManager = BiometricManager.from(context)
val isCapable = when (biometricManager.canAuthenticate()) {
    BiometricManager.BIOMETRIC_SUCCESS,
    BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED -> true
    else -> false
}

The result of this just tells us that the device is capable of using the BiometricPrompt.

Step 2) Ask PackageManager For Available Features

There are currently only 3 types of Biometrics as of API 29 (Android 10).  The Android PackageManager can be queried to see if these features are available on the device.

// Get Package Manager
val packageManager : PackageManager = context.packageManager

Based on these, you should know, but there are edge cases:

  • One is available – If only one is available and the rest are not, you should feel pretty confident that you know the exact type of biometric that will be used.
  • More than one available – It is possible that a device could have more than one biometric feature.  It could have Face Unlock and Fingerprint.  Android is an open platform, and Google has said that OEMs could do this if they choose.
  • None are available –  If this is the case, and the BiometricManager said you canAuthenticate(), then some sort of biometric is available that we have never seen before.  This could be the case if this code is run on a future version of Android with a Biometric type we don’t know about.

Step 3) Determine Supported Biometrics

Based on all the logic above, we will end up with one of the following results.

sealed class Biometrics {
    object None : Biometrics()
    sealed class Available : Biometrics() {
        object Face : Available()
        object Fingerprint : Available()
        object Iris : Available()
        object Multiple : Available()
        object Unknown : Available()
    }
}

You can then use a “when” statement to create user messaging for a specific biometric hardware type. 🎉

What are future Biometric Types?

We don’t know yet.

Biometric APIs are meant to be more future-looking. We “could” expose something like authenticate(type, info, crypto) etc, but it exposes more API surface and thus has the chance of causing more fragmentation across OEMs.
– Googler’s Response on Issue Tracker

In order to be more open ended, these Biometric APIs are built in a way where generic messaging is the recommended approach currently.

Conflicts with Material Design Guidelines

The Material Design guide for Fingerprint explicitly says to maintain consistency with Android Settings. Such as “Confirm fingerprint”.  The BiometricManager tells us if a user “canAuthenticate()“, but doesn’t tell us what types of Biometrics are available on the device or which one (if more than one) is currently enabled.  The rationale for this:

If new sensors are developed, we would need to keep updating the “type” list, and apps would also need to keep updating to use the new types. Perhaps there’s a way to make that work, just we haven’t spent much time investigating.
– Googler’s Response on Issue Tracker

I think this is a great way to do it, and aligns with user expectations, but this is not available with current Biometric APIs. 😞

Pixel 3 Settings Pixel 4 Settings

Conclusion

This all sounds like a lot of work.  You can just use “Biometric” and you’ll probably be fine.  Users will get used to it eventually, right?  No matter how hard we try at this point, we will end up having to use that terminology in the cases where “Multiple” or “Unknown” biometric features are available anyways.

It kinda stinks that we got forced to use these APIs since FingerprintManager is deprecated, and the Biometric APIs have a lot of these little workarounds you may need to do.  I understand the rationale behind it from an OS standpoint, but I hope that Google exposes the type(s) of Biometric available on the device to use.  That way we are sure, and aren’t doing all this work to try and figure it out.

Recommendations

  1. Must: Use the AndroidX Library.  It’s a wrapper on top of the Android OS APIs and deals with specific workarounds, as well as provides a FingerprintManager fallback for devices prior to API 28 which don’t have a BiometricPrompt in the OS.
  2. Recommended: Checkout Biometricks which is a library in development to do what is mentioned in this article.  It has a sample app and more.
  3. Recommended: Do some user testing.  I’m giving some advice from what I’ve seen, but you may find something different with your users.  Your users are your source of truth.

Disclaimers

  • This is a UX guide, and not anything related to security of using Biometric features of Android.
  • These are my personal observations and opinions.

Related Links

Why We Need “fat” AARs for Android Libraries

I want the ability to create a single (“fat”) AAR artifact from multiple Android Libraries (all from source).  Non-source, transitive dependencies will still be pulled in via a pom.xml file.

Requirements:

  1. I want to write and SDK that would be used by 3rd parties and possibly internal teams.  I want to write modular code on my side, with clean separation of concerns, yet only provide a single AAR artifact to users of my library.  Users of my library don’t need to know how I architected the internals, and in some cases I don’t want them to know.  I want to obfuscate my internal implementations to avoid accidental usage as well as for some security.
  2. I want to shrink and optimize my code with ProGuard (which is being replaced by R8) on my entire library, and generate only a single AAR file.  With current tooling, each module is only aware of its own code and resources when ProGuard is run.  This means that I can’t optimize or obfuscate my entire library/SDK in its entirety.  Because I must run ProGuard on each module individually at the current time, you end up with NoClassDefFoundErrors if you try to be aggressive with obfuscation.

The Use Case

For this post, think of an SDK you would get from an external vendor, or another team that contains their shrink-wrapped code that you need to plop into your app.  For an app like Twitter, that could mean:

  • Login page library
  • Video streaming player library
  • Home feed library
  • Emoji support library
  • etc.

Note: With the Twitter example I just mean to show that you can bundle discrete components of an app with clear boundaries between them.

When you get into a big app, you have to separate out components, and using Android Libraries to do this is a great decision.  That being said, I would never want “fat” AARs to be the only way to do things.  I just think it would solve some use cases when you are creating and SDK to be used by 3rd parties that don’t need to know how the internals of your code work.

Technical Reasons: Why Creating a “FAT” AAR Doesn’t Work

Apps/APKs can combine as many AARs into a single APK artifact.  That’s because there is a Manifest merge process that defines rules on how the AndroidManifest.xml, resources and assets are merged for the resulting APK file.  At the time the APK is created, ProGuard can be applied to optimize all byte code, remove unused classes, and perform code obfuscation.

Didn’t Someone Create a Library to Do This?

Kinda… A long time ago.  There was a partial workaround for manifest merging for Android Libraries using Android Gradle Plugin 2.x called “FAT” AAR, but it was limited, unofficial, and no longer works with Gradle 3.x.  There seems to be no plans to make it work with newer versions of Gradle.  It esentially tried to do its own hacky version of Manifest merging.

Argument Against: You only need to specify a single dependency in your build.gradle to import all of the transitive libraries. Why are you complaining?

This is true for the use case where you publish your artifacts correctly to a public Maven repository.  Your user would only need to care about adding a single Gradle dependency, and the others would be pulled down transitively.  All they would need to add is “com.example:my-lib:1.0.0” to their Gradle dependencies. This works great in a lot of cases, like the Android Support Library, where the dependencies are all published publicly, and users can cherry-pick the pieces they want.

In the use case I’m requesting this for, existing methods aren’t great for 2 reasons.

  1. I want to control what my shrink-wrapped artifacts look like, while still maintaining modularized code internally.  It’s easier to hand over a single AAR file when you need to distribute a library via a non-public Maven repository. Yes, I could ask users to create a file-based maven repository in the project, but that is ugly.
  2. I want to shrink and optimize all of my library before delivering it to users.  It is only possible to run ProGuard on each module individually at the current time, which means that code optimizations and obfuscation breaks when it is used aggressively on each module independently.

Finally

I’ve created this post to explain some of the current limits of building Android Libraries with the Android Gradle Plugin that I’ve run into, and to make a plea to the Android Tooling team to accept the issue for newer versions of Android Gradle Plugin.  ⬇Xavier Ducrohet, the Android SDK Tech Lead said this is being considered for Android Gradle Plugin 3.3, but isn’t on the roadmap yet.  Since 3.2 is almost out the door, I figured now is a good time to make a push for this issue.

If you have this same issue or use case, please ⭐ the issue, but also comment about how this uniquely effects your development.

Android Zombie Processes – Is My App Still Alive?

To the eye, it may seem like your Android application is “dead” when you “kill” the app via the task manager, but you may be surprised that in many cases, the application process lives on.

Here are some ADB commands that you can diagnose and investigate what’s going on, on the device.

Determine Running Processes via ADB

All Processes

adb shell ps

Your Process

adb shell ps | grep com.mydomain.myappnamegoeshere

An Android Service registered to your application will prevent your process from being killed if it is currently running.  Therefore you need to be careful and aware that your singleton variables in your application are aware of this.  Read more about this here: Processes and Application Life Cycle.

void onTaskRemoved (Intent rootIntent)

You can leverage the Service::onTaskRemoved() method in Android to catch this “swipe” event where the user intends to “kill” your app via the task manager, even if services continue to run in the background.  This can be useful to catch this event if you want to end a user session for instance.  This can also be useful if your intention is to stop services when the user dismisses your app, as you can programatically stop the service at this point in time as well.

Note: If you have set ServiceInfo.FLAG_STOP_WITH_TASK when starting the Service, then you will not receive this callback; instead, the service will simply be stopped.

Security Tip: Protecting Session Sensitive Responses with Retrofit 2 and okhttp 3

Problem Statement:

A user could receive and view data that is not theirs, and we must prevent this from happening in a secure application.  Here is a diagram of how this could happen:

Flow Diagram of the Session Mismatch Issue

 

Implementation options with Retrofit 2 and okhttp 3:

Option 1:

Write a custom Retrofit 2 CallAdapter that blocks the response from being processed or passes an exception to the onFailure() method.

  • PROS:
    • Great if you use Retrofit 2 exclusively for session sensitive calls.
    • This can prevent the callback from being invoked, or you could call Retrofit 2’s onFailure() method.
  • CONS:
    • Retrofit 2 CallAdapter is complex and you have to write one for both plain Callbacks as well as for RxJava (if you are using both).
    • We’d have to copy the existing CallAdapter implementation in retrofit2.ExecutorCallAdapterFactory and modify it as it’s a final class.
    • This only works for Retrofit 2 calls, but not all networking calls made through okhttp 3.

Option 2:

When the client session is invalidated, use okhttp 3’s Dispatcher to cancel all running and queued calls.

  • PROS:
    • Very effective. All calls would immediately be cancelled.
  • CONS:
    • If there is a call like “Update Profile” that is still occurring, it would be cancelled, which is not desirable.
    • If there is an unauthenticated call happening, you’d have to ensure that was being executed on non session sensitive Retrofit 2 or okhttp 3 instance to avoid unwanted termination.

Option 3:

Same as the previous option, but instead occurs when a new client session is started, instead of when an old one ends.

  • PROS:
    • Very effective. All calls would immediately be cancelled.
  • CONS:
    • You would have to ensure this code got run before you kicked off any session sensitive calls, otherwise they would be immediately cancelled.
    • If there is an unauthenticated call happening in the background, you’d have to ensure that was being executed on non session sensitive Retrofit 2 or okhttp 3 instance to avoid unwanted termination.

Option 4:

Using an okhttp 3 Network Interceptor to return back an HTTP Response with a custom response code like 999 and removing the response body.

  • PROS:
    • Will work for:
      • All okhttp 3 calls.
      • Retrofit 2 Callback calls.
      • Retrofit 2 RxJava calls.
  • CONS:
    • It will appear like the HTTP response came back from the server so you will have to have custom logic in your response handler to check and see if this response has a HTTP status code of 999.
    • It feels a little “hacky”… but would prevent the security hole.

Option 5: (My Choice)

Using an okhttp 3 Network Interceptor to throw a custom SessionMismatchException when this problem is detected, and handle the Exception appropriately.

  • PROS:
    • Will work for:
      • All okhttp 3 calls
      • Retrofit 2 Callback Calls
      • Retrofit 2 RxJava Calls
    • This is truly an “Exception” scenario, so this makes sense.
    • The request is executed fully, but will not be received by the client. (This could be a “con” depending on your use case)
  • CONS:
    • You must code your onFailure and onError handlers to appropriately handle this SessionMismatchException type.
    • If you just extend IOException, okhttp 3 will by default retry the HTTP call.  However, if you extend java.net.SocketTimeoutException, okhttp 3 will not retry.

My Choice: Option 5, throwing a custom SessionMismatchException.  This seemed to be the most flexible and intuitive since this truly is an Exception/Failure case.  I’ve provided a sample implementation of this below.

Assumption: You have a  “SessionManager” in your Android code which is aware of the current session.

Let me know if this was helpful, or if you’d do something different on Twitter at @HandstandSam

Enabling Cross-Origin Requests in Chrome from a HTML file:///

To allow cross-origin AJAX request using POST/PUT/DELETE requests to occur from a local html file that you open in your browser such as:

file:///Users/handstandsam/index.html

On your Mac, quit Chrome completely, then re-launch it using the following Terminal command:

open /Applications/Google\ Chrome.app/ –args –disable-web-security

That’s it.

WARNING: This does disable web security, so be cautious about what sites you access while Chrome is launched in this mode.

More info on Stack Overflow: http://stackoverflow.com/questions/3102819/disable-same-origin-policy-in-chrome

Android HTTPS Cert Pinning (Part 1) – Obtaining CA Certificates and Public SSL Key

What is certificate pinning?

Ensures a client is connecting over HTTPS to the intended server ONLY and no other.  This is achieved by including public server certificate information on the client and not relying on the device’s trust store (such as the one on Android or the JVM).

This trust store can be augmented by adding in additional Certificate Authority (CA) Certs and then HTTPs traffic can still be monitored.  A common development use of monitoring HTTPS traffic is using Charles Proxy.

Obtaining A Server’s Public SSL Key

openssl s_client -connect www.google.com:443 | openssl x509 -pubkey -noout

depth=2 /C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
verify error:num=20:unable to get local issuer certificate
verify return:0
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhtxFolwNJBGuhYRGDiNF
2Av9jTt0c2vk5mLBrO9td2hFyvw0B0fPpxbkOm72Cd4OnGVXxIB0hp1XRWXuyP+p
FMHmXSshVWDIrcAwjR5r+WnAqrLacZJNHkDOWO+COY8CUHGTn9YfwKwuHQROp6aH
Yu7YhppMXu3dL1kZ55AzYdwgYVc6BdxmDsGWRZbgZ0qt/QQC0zmbR+hLpZAKhHmN
VnBRXYz5q+XLEBmjQnwVmwMzPCvZFzNEWan0wQsCRqcJ19lO5hLxn4O2T718qF2h
cd1sH1RL6HlhUxJe09L3yoGCMoENIq6ywIrVgFsZtyhg8TMyCZuRtyCS+ux9ma0A
7wIDAQAB
-----END PUBLIC KEY-----

Decoding a Certificate

openssl s_client -connect www.google.com:443 | openssl x509 -text

depth=2 /C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
verify error:num=20:unable to get local issuer certificate
verify return:0
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            01:30:5c:d0:43:91:9d:86
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, O=Google Inc, CN=Google Internet Authority G2
        Validity
            Not Before: Jan 15 12:20:52 2016 GMT
            Not After : Apr 14 00:00:00 2016 GMT
        Subject: C=US, ST=California, L=Mountain View, O=Google Inc, CN=www.google.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (2048 bit)
                Modulus (2048 bit):
                    00:86:dc:45:a2:5c:0d:24:11:ae:85:84:46:0e:23:
                    45:d8:0b:fd:8d:3b:74:73:6b:e4:e6:62:c1:ac:ef:
                    6d:77:68:45:ca:fc:34:07:47:cf:a7:16:e4:3a:6e:
                    f6:09:de:0e:9c:65:57:c4:80:74:86:9d:57:45:65:
                    ee:c8:ff:a9:14:c1:e6:5d:2b:21:55:60:c8:ad:c0:
                    30:8d:1e:6b:f9:69:c0:aa:b2:da:71:92:4d:1e:40:
                    ce:58:ef:82:39:8f:02:50:71:93:9f:d6:1f:c0:ac:
                    2e:1d:04:4e:a7:a6:87:62:ee:d8:86:9a:4c:5e:ed:
                    dd:2f:59:19:e7:90:33:61:dc:20:61:57:3a:05:dc:
                    66:0e:c1:96:45:96:e0:67:4a:ad:fd:04:02:d3:39:
                    9b:47:e8:4b:a5:90:0a:84:79:8d:56:70:51:5d:8c:
                    f9:ab:e5:cb:10:19:a3:42:7c:15:9b:03:33:3c:2b:
                    d9:17:33:44:59:a9:f4:c1:0b:02:46:a7:09:d7:d9:
                    4e:e6:12:f1:9f:83:b6:4f:bd:7c:a8:5d:a1:71:dd:
                    6c:1f:54:4b:e8:79:61:53:12:5e:d3:d2:f7:ca:81:
                    82:32:81:0d:22:ae:b2:c0:8a:d5:80:5b:19:b7:28:
                    60:f1:33:32:09:9b:91:b7:20:92:fa:ec:7d:99:ad:
                    00:ef
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Extended Key Usage: 
                TLS Web Server Authentication, TLS Web Client Authentication
            X509v3 Subject Alternative Name: 
                DNS:www.google.com
            Authority Information Access: 
                CA Issuers - URI:http://pki.google.com/GIAG2.crt
                OCSP - URI:http://clients1.google.com/ocsp

            X509v3 Subject Key Identifier: 
                9F:FB:21:7B:F9:2B:DF:0F:8E:2F:0F:65:C2:72:A5:AF:9C:0E:6F:D4
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Authority Key Identifier: 
                keyid:4A:DD:06:16:1B:BC:F6:68:B5:76:F5:81:B6:BB:62:1A:BA:5A:81:2F

            X509v3 Certificate Policies: 
                Policy: 1.3.6.1.4.1.11129.2.5.1
                Policy: 2.23.140.1.2.2

            X509v3 CRL Distribution Points: 
                URI:http://pki.google.com/GIAG2.crl

    Signature Algorithm: sha256WithRSAEncryption
        95:ef:38:55:18:dc:c9:67:c4:11:17:ef:57:de:f1:3a:bf:0d:
        0b:fc:2e:f1:2f:be:cd:ee:a5:19:94:18:7c:72:14:b8:e6:d0:
        da:b9:f7:79:31:3b:49:f5:1b:66:47:68:43:80:14:1e:8c:9f:
        3d:bb:77:e2:c9:7c:c4:ab:b2:10:39:ae:0a:0c:55:48:bc:a1:
        77:03:84:e9:56:8e:8f:61:fe:4b:57:c6:78:df:69:9c:4a:60:
        eb:00:b6:96:c1:ec:0f:24:42:1b:5d:9f:10:18:10:6e:e3:72:
        8d:3c:e9:a2:90:b1:4c:f1:2a:21:74:dd:d1:d5:92:33:61:bc:
        52:46:bd:c6:65:e6:37:aa:7d:39:ad:75:ef:87:89:e0:e9:eb:
        de:9f:a9:9a:47:1a:9e:99:ee:7a:62:60:12:ed:14:0c:f8:63:
        f8:5d:3e:8a:ab:83:d5:4c:36:9f:a7:ef:8e:09:51:ff:c1:68:
        c1:82:6b:7c:29:f5:6e:25:5d:44:7f:5e:64:0e:33:e8:c4:fc:
        40:5d:67:9e:56:d8:d7:77:bf:bb:5b:13:db:2c:35:d5:43:82:
        0f:f5:c3:9b:ff:ec:2f:38:00:db:36:39:df:4e:85:20:d1:08:
        57:a0:f9:4d:cc:8f:64:bf:35:05:f9:98:58:f3:6a:55:54:13:
        d1:77:92:dd
-----BEGIN CERTIFICATE-----
MIIEgDCCA2igAwIBAgIIATBc0EORnYYwDQYJKoZIhvcNAQELBQAwSTELMAkGA1UE
BhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2dsZSBJbnRl
cm5ldCBBdXRob3JpdHkgRzIwHhcNMTYwMTE1MTIyMDUyWhcNMTYwNDE0MDAwMDAw
WjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwN
TW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UEAwwOd3d3
Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCG3EWi
XA0kEa6FhEYOI0XYC/2NO3Rza+TmYsGs7213aEXK/DQHR8+nFuQ6bvYJ3g6cZVfE
gHSGnVdFZe7I/6kUweZdKyFVYMitwDCNHmv5acCqstpxkk0eQM5Y74I5jwJQcZOf
1h/ArC4dBE6npodi7tiGmkxe7d0vWRnnkDNh3CBhVzoF3GYOwZZFluBnSq39BALT
OZtH6EulkAqEeY1WcFFdjPmr5csQGaNCfBWbAzM8K9kXM0RZqfTBCwJGpwnX2U7m
EvGfg7ZPvXyoXaFx3WwfVEvoeWFTEl7T0vfKgYIygQ0irrLAitWAWxm3KGDxMzIJ
m5G3IJL67H2ZrQDvAgMBAAGjggFLMIIBRzAdBgNVHSUEFjAUBggrBgEFBQcDAQYI
KwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYBBQUHAQEE
XDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3J0
MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9vY3NwMB0G
A1UdDgQWBBSf+yF7+SvfD44vD2XCcqWvnA5v1DAMBgNVHRMBAf8EAjAAMB8GA1Ud
IwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMCEGA1UdIAQaMBgwDAYKKwYBBAHW
eQIFATAIBgZngQwBAgIwMAYDVR0fBCkwJzAloCOgIYYfaHR0cDovL3BraS5nb29n
bGUuY29tL0dJQUcyLmNybDANBgkqhkiG9w0BAQsFAAOCAQEAle84VRjcyWfEERfv
V97xOr8NC/wu8S++ze6lGZQYfHIUuObQ2rn3eTE7SfUbZkdoQ4AUHoyfPbt34sl8
xKuyEDmuCgxVSLyhdwOE6VaOj2H+S1fGeN9pnEpg6wC2lsHsDyRCG12fEBgQbuNy
jTzpopCxTPEqIXTd0dWSM2G8Uka9xmXmN6p9Oa1174eJ4Onr3p+pmkcanpnuemJg
Eu0UDPhj+F0+iquD1Uw2n6fvjglR/8FowYJrfCn1biVdRH9eZA4z6MT8QF1nnlbY
13e/u1sT2yw11UOCD/XDm//sLzgA2zY5306FINEIV6D5TcyPZL81BfmYWPNqVVQT
0XeS3Q==
-----END CERTIFICATE-----

Obtaining A Server’s Public CA Certificate Chain

Screen Shot 2016-01-23 at 7.34.52 PM Screen Shot 2016-01-23 at 7.35.13 PM

openssl s_client -connect www.google.com:443 -showcerts

CONNECTED(00000003)
depth=2 /C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=google.com
   i:/C=US/O=Google Inc/CN=Google Internet Authority G2
-----BEGIN CERTIFICATE-----
MIIf+DCCHuCgAwIBAgIICakyfYEPpYQwDQYJKoZIhvcNAQELBQAwSTELMAkGA1UE
BhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2dsZSBJbnRl
cm5ldCBBdXRob3JpdHkgRzIwHhcNMTYwMTE1MTIxMjU1WhcNMTYwNDE0MDAwMDAw
WjBkMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwN
TW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzETMBEGA1UEAwwKZ29v
Z2xlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPcEGWpooVGn
J7zMUVHcp9BENDMB01hNJAHbhBJUVFTGQzeZzu6EGtTh9HKJfejqzpAaTkC8Q1ZI
gAUF5A8q4JKfs+C3YoxOXggEAvuSVA+I8UtPyVY0nJr1oumG18o9bTi8T2ABPlBq
Ef0BXhukoi8F6uYRbxBDEWjjKuOkw5sDWqw8cFoFRA7Ly2C+S5oR53s0Lhgo0T3G
zkRUT3WxwZrHFcBdeMUQn+Jd5WgfvkGGbUKGYINKZzGSc129MwL2NMF3MpKm0bi+
JDDebYfmt6LoSCTxLRhiXrfo38cwMZWYNZIK42hhteiREmKKzM1G/KpzgsuJ/wRc
dwdagyDnxGUCAwEAAaOCHMcwghzDMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF
BQcDAjCCG5MGA1UdEQSCG4owghuGggpnb29nbGUuY29tggoqLjJtZG4ubmV0gg0q
LmFuZHJvaWQuY29tghYqLmFwcGVuZ2luZS5nb29nbGUuY29tghQqLmF1LmRvdWJs
ZWNsaWNrLm5ldIILKi5jYy1kdC5jb22CEiouY2xvdWQuZ29vZ2xlLmNvbYIUKi5k
ZS5kb3VibGVjbGljay5uZXSCESouZG91YmxlY2xpY2suY29tghEqLmRvdWJsZWNs
aWNrLm5ldIIVKi5mbHMuZG91YmxlY2xpY2submV0ghQqLmZyLmRvdWJsZWNsaWNr
Lm5ldIIWKi5nb29nbGUtYW5hbHl0aWNzLmNvbYILKi5nb29nbGUuYWOCCyouZ29v
Z2xlLmFkggsqLmdvb2dsZS5hZYILKi5nb29nbGUuYWaCCyouZ29vZ2xlLmFnggsq
Lmdvb2dsZS5hbIILKi5nb29nbGUuYW2CCyouZ29vZ2xlLmFzggsqLmdvb2dsZS5h
dIILKi5nb29nbGUuYXqCCyouZ29vZ2xlLmJhggsqLmdvb2dsZS5iZYILKi5nb29n
bGUuYmaCCyouZ29vZ2xlLmJnggsqLmdvb2dsZS5iaYILKi5nb29nbGUuYmqCCyou
Z29vZ2xlLmJzggsqLmdvb2dsZS5idIILKi5nb29nbGUuYnmCCyouZ29vZ2xlLmNh
ggwqLmdvb2dsZS5jYXSCCyouZ29vZ2xlLmNjggsqLmdvb2dsZS5jZIILKi5nb29n
bGUuY2aCCyouZ29vZ2xlLmNnggsqLmdvb2dsZS5jaIILKi5nb29nbGUuY2mCCyou
Z29vZ2xlLmNsggsqLmdvb2dsZS5jbYILKi5nb29nbGUuY26CDiouZ29vZ2xlLmNv
LmFvgg4qLmdvb2dsZS5jby5id4IOKi5nb29nbGUuY28uY2uCDiouZ29vZ2xlLmNv
LmNygg4qLmdvb2dsZS5jby5odYIOKi5nb29nbGUuY28uaWSCDiouZ29vZ2xlLmNv
Lmlsgg4qLmdvb2dsZS5jby5pbYIOKi5nb29nbGUuY28uaW6CDiouZ29vZ2xlLmNv
Lmplgg4qLmdvb2dsZS5jby5qcIIOKi5nb29nbGUuY28ua2WCDiouZ29vZ2xlLmNv
Lmtygg4qLmdvb2dsZS5jby5sc4IOKi5nb29nbGUuY28ubWGCDiouZ29vZ2xlLmNv
Lm16gg4qLmdvb2dsZS5jby5ueoIOKi5nb29nbGUuY28udGiCDiouZ29vZ2xlLmNv
LnR6gg4qLmdvb2dsZS5jby51Z4IOKi5nb29nbGUuY28udWuCDiouZ29vZ2xlLmNv
LnV6gg4qLmdvb2dsZS5jby52ZYIOKi5nb29nbGUuY28udmmCDiouZ29vZ2xlLmNv
Lnphgg4qLmdvb2dsZS5jby56bYIOKi5nb29nbGUuY28ueneCDCouZ29vZ2xlLmNv
bYIPKi5nb29nbGUuY29tLmFmgg8qLmdvb2dsZS5jb20uYWeCDyouZ29vZ2xlLmNv
bS5haYIPKi5nb29nbGUuY29tLmFygg8qLmdvb2dsZS5jb20uYXWCDyouZ29vZ2xl
LmNvbS5iZIIPKi5nb29nbGUuY29tLmJogg8qLmdvb2dsZS5jb20uYm6CDyouZ29v
Z2xlLmNvbS5ib4IPKi5nb29nbGUuY29tLmJygg8qLmdvb2dsZS5jb20uYnmCDyou
Z29vZ2xlLmNvbS5ieoIPKi5nb29nbGUuY29tLmNugg8qLmdvb2dsZS5jb20uY2+C
DyouZ29vZ2xlLmNvbS5jdYIPKi5nb29nbGUuY29tLmN5gg8qLmdvb2dsZS5jb20u
ZG+CDyouZ29vZ2xlLmNvbS5lY4IPKi5nb29nbGUuY29tLmVngg8qLmdvb2dsZS5j
b20uZXSCDyouZ29vZ2xlLmNvbS5maoIPKi5nb29nbGUuY29tLmdlgg8qLmdvb2ds
ZS5jb20uZ2iCDyouZ29vZ2xlLmNvbS5naYIPKi5nb29nbGUuY29tLmdygg8qLmdv
b2dsZS5jb20uZ3SCDyouZ29vZ2xlLmNvbS5oa4IPKi5nb29nbGUuY29tLmlxgg8q
Lmdvb2dsZS5jb20uam2CDyouZ29vZ2xlLmNvbS5qb4IPKi5nb29nbGUuY29tLmto
gg8qLmdvb2dsZS5jb20ua3eCDyouZ29vZ2xlLmNvbS5sYoIPKi5nb29nbGUuY29t
Lmx5gg8qLmdvb2dsZS5jb20ubW2CDyouZ29vZ2xlLmNvbS5tdIIPKi5nb29nbGUu
Y29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIPKi5nb29n
bGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5uaYIPKi5n
b29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNvbS5vbYIP
Ki5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xlLmNvbS5w
Z4IPKi5nb29nbGUuY29tLnBogg8qLmdvb2dsZS5jb20ucGuCDyouZ29vZ2xlLmNv
bS5wbIIPKi5nb29nbGUuY29tLnBygg8qLmdvb2dsZS5jb20ucHmCDyouZ29vZ2xl
LmNvbS5xYYIPKi5nb29nbGUuY29tLnJ1gg8qLmdvb2dsZS5jb20uc2GCDyouZ29v
Z2xlLmNvbS5zYoIPKi5nb29nbGUuY29tLnNngg8qLmdvb2dsZS5jb20uc2yCDyou
Z29vZ2xlLmNvbS5zdoIPKi5nb29nbGUuY29tLnRqgg8qLmdvb2dsZS5jb20udG6C
DyouZ29vZ2xlLmNvbS50coIPKi5nb29nbGUuY29tLnR3gg8qLmdvb2dsZS5jb20u
dWGCDyouZ29vZ2xlLmNvbS51eYIPKi5nb29nbGUuY29tLnZjgg8qLmdvb2dsZS5j
b20udmWCDyouZ29vZ2xlLmNvbS52boILKi5nb29nbGUuY3aCCyouZ29vZ2xlLmN6
ggsqLmdvb2dsZS5kZYILKi5nb29nbGUuZGqCCyouZ29vZ2xlLmRrggsqLmdvb2ds
ZS5kbYILKi5nb29nbGUuZHqCCyouZ29vZ2xlLmVlggsqLmdvb2dsZS5lc4IMKi5n
b29nbGUuZXVzggsqLmdvb2dsZS5maYILKi5nb29nbGUuZm2CCyouZ29vZ2xlLmZy
ggwqLmdvb2dsZS5mcmyCCyouZ29vZ2xlLmdhggwqLmdvb2dsZS5nYWyCCyouZ29v
Z2xlLmdlggsqLmdvb2dsZS5nZ4ILKi5nb29nbGUuZ2yCCyouZ29vZ2xlLmdtggsq
Lmdvb2dsZS5ncIILKi5nb29nbGUuZ3KCCyouZ29vZ2xlLmd5ggsqLmdvb2dsZS5o
a4ILKi5nb29nbGUuaG6CCyouZ29vZ2xlLmhyggsqLmdvb2dsZS5odIILKi5nb29n
bGUuaHWCCyouZ29vZ2xlLmllggsqLmdvb2dsZS5pbYILKi5nb29nbGUuaW6CDSou
Z29vZ2xlLmluZm+CCyouZ29vZ2xlLmlxggsqLmdvb2dsZS5pcoILKi5nb29nbGUu
aXOCCyouZ29vZ2xlLml0gg4qLmdvb2dsZS5pdC5hb4ILKi5nb29nbGUuamWCCyou
Z29vZ2xlLmpvgg0qLmdvb2dsZS5qb2JzggsqLmdvb2dsZS5qcIILKi5nb29nbGUu
a2eCCyouZ29vZ2xlLmtpggsqLmdvb2dsZS5reoILKi5nb29nbGUubGGCCyouZ29v
Z2xlLmxpggsqLmdvb2dsZS5sa4ILKi5nb29nbGUubHSCCyouZ29vZ2xlLmx1ggsq
Lmdvb2dsZS5sdoILKi5nb29nbGUubWSCCyouZ29vZ2xlLm1lggsqLmdvb2dsZS5t
Z4ILKi5nb29nbGUubWuCCyouZ29vZ2xlLm1sggsqLmdvb2dsZS5tboILKi5nb29n
bGUubXOCCyouZ29vZ2xlLm11ggsqLmdvb2dsZS5tdoILKi5nb29nbGUubXeCCyou
Z29vZ2xlLm5lgg4qLmdvb2dsZS5uZS5qcIIMKi5nb29nbGUubmV0ggsqLmdvb2ds
ZS5uZ4ILKi5nb29nbGUubmyCCyouZ29vZ2xlLm5vggsqLmdvb2dsZS5ucoILKi5n
b29nbGUubnWCDyouZ29vZ2xlLm9mZi5haYILKi5nb29nbGUucGuCCyouZ29vZ2xl
LnBsggsqLmdvb2dsZS5wboILKi5nb29nbGUucHOCCyouZ29vZ2xlLnB0ggsqLmdv
b2dsZS5yb4ILKi5nb29nbGUucnOCCyouZ29vZ2xlLnJ1ggsqLmdvb2dsZS5yd4IL
Ki5nb29nbGUuc2OCCyouZ29vZ2xlLnNlggsqLmdvb2dsZS5zaIILKi5nb29nbGUu
c2mCCyouZ29vZ2xlLnNrggsqLmdvb2dsZS5zbYILKi5nb29nbGUuc26CCyouZ29v
Z2xlLnNvggsqLmdvb2dsZS5zcoILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggwq
Lmdvb2dsZS50ZWyCCyouZ29vZ2xlLnRnggsqLmdvb2dsZS50a4ILKi5nb29nbGUu
dGyCCyouZ29vZ2xlLnRtggsqLmdvb2dsZS50boILKi5nb29nbGUudG+CCyouZ29v
Z2xlLnR0ggsqLmdvb2dsZS51YYILKi5nb29nbGUudXOCCyouZ29vZ2xlLnV6ggsq
Lmdvb2dsZS52Z4ILKi5nb29nbGUudnWCCyouZ29vZ2xlLndzghIqLmdvb2dsZWFk
YXBpcy5jb22CFSouZ29vZ2xlYWRzc2VydmluZy5jboIPKi5nb29nbGVhcGlzLmNu
ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYIRKi5nb29nbGV2aWRlby5jb22CDCouZ3N0
YXRpYy5jboINKi5nc3RhdGljLmNvbYIKKi5ndnQxLmNvbYIKKi5ndnQyLmNvbYIU
Ki5qcC5kb3VibGVjbGljay5uZXSCFCoubWV0cmljLmdzdGF0aWMuY29tghQqLnVr
LmRvdWJsZWNsaWNrLm5ldIIMKi51cmNoaW4uY29tghAqLnVybC5nb29nbGUuY29t
ghYqLnlvdXR1YmUtbm9jb29raWUuY29tgg0qLnlvdXR1YmUuY29tghYqLnlvdXR1
YmVlZHVjYXRpb24uY29tggsqLnl0aW1nLmNvbYIVYWQubW8uZG91YmxlY2xpY2su
bmV0ghphbmRyb2lkLmNsaWVudHMuZ29vZ2xlLmNvbYILYW5kcm9pZC5jb22CD2Rv
dWJsZWNsaWNrLm5ldIIEZy5jb4IGZ29vLmdsghRnb29nbGUtYW5hbHl0aWNzLmNv
bYIJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJZ29vZ2xlLmFmggln
b29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29nbGUuYXOCCWdvb2ds
ZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5iZYIJZ29vZ2xlLmJm
gglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqgglnb29nbGUuYnOCCWdv
b2dsZS5idIIJZ29vZ2xlLmJ5gglnb29nbGUuY2GCCmdvb2dsZS5jYXSCCWdvb2ds
ZS5jY4IJZ29vZ2xlLmNkgglnb29nbGUuY2aCCWdvb2dsZS5jZ4IJZ29vZ2xlLmNo
gglnb29nbGUuY2mCCWdvb2dsZS5jbIIJZ29vZ2xlLmNtgglnb29nbGUuY26CDGdv
b2dsZS5jby5hb4IMZ29vZ2xlLmNvLmJ3ggxnb29nbGUuY28uY2uCDGdvb2dsZS5j
by5jcoIMZ29vZ2xlLmNvLmh1ggxnb29nbGUuY28uaWSCDGdvb2dsZS5jby5pbIIM
Z29vZ2xlLmNvLmltggxnb29nbGUuY28uaW6CDGdvb2dsZS5jby5qZYIMZ29vZ2xl
LmNvLmpwggxnb29nbGUuY28ua2WCDGdvb2dsZS5jby5rcoIMZ29vZ2xlLmNvLmxz
ggxnb29nbGUuY28ubWGCDGdvb2dsZS5jby5teoIMZ29vZ2xlLmNvLm56ggxnb29n
bGUuY28udGiCDGdvb2dsZS5jby50eoIMZ29vZ2xlLmNvLnVnggxnb29nbGUuY28u
dWuCDGdvb2dsZS5jby51eoIMZ29vZ2xlLmNvLnZlggxnb29nbGUuY28udmmCDGdv
b2dsZS5jby56YYIMZ29vZ2xlLmNvLnptggxnb29nbGUuY28ueneCDWdvb2dsZS5j
b20uYWaCDWdvb2dsZS5jb20uYWeCDWdvb2dsZS5jb20uYWmCDWdvb2dsZS5jb20u
YXKCDWdvb2dsZS5jb20uYXWCDWdvb2dsZS5jb20uYmSCDWdvb2dsZS5jb20uYmiC
DWdvb2dsZS5jb20uYm6CDWdvb2dsZS5jb20uYm+CDWdvb2dsZS5jb20uYnKCDWdv
b2dsZS5jb20uYnmCDWdvb2dsZS5jb20uYnqCDWdvb2dsZS5jb20uY26CDWdvb2ds
ZS5jb20uY2+CDWdvb2dsZS5jb20uY3WCDWdvb2dsZS5jb20uY3mCDWdvb2dsZS5j
b20uZG+CDWdvb2dsZS5jb20uZWOCDWdvb2dsZS5jb20uZWeCDWdvb2dsZS5jb20u
ZXSCDWdvb2dsZS5jb20uZmqCDWdvb2dsZS5jb20uZ2WCDWdvb2dsZS5jb20uZ2iC
DWdvb2dsZS5jb20uZ2mCDWdvb2dsZS5jb20uZ3KCDWdvb2dsZS5jb20uZ3SCDWdv
b2dsZS5jb20uaGuCDWdvb2dsZS5jb20uaXGCDWdvb2dsZS5jb20uam2CDWdvb2ds
ZS5jb20uam+CDWdvb2dsZS5jb20ua2iCDWdvb2dsZS5jb20ua3eCDWdvb2dsZS5j
b20ubGKCDWdvb2dsZS5jb20ubHmCDWdvb2dsZS5jb20ubW2CDWdvb2dsZS5jb20u
bXSCDWdvb2dsZS5jb20ubXiCDWdvb2dsZS5jb20ubXmCDWdvb2dsZS5jb20ubmGC
DWdvb2dsZS5jb20ubmaCDWdvb2dsZS5jb20ubmeCDWdvb2dsZS5jb20ubmmCDWdv
b2dsZS5jb20ubnCCDWdvb2dsZS5jb20ubnKCDWdvb2dsZS5jb20ub22CDWdvb2ds
ZS5jb20ucGGCDWdvb2dsZS5jb20ucGWCDWdvb2dsZS5jb20ucGeCDWdvb2dsZS5j
b20ucGiCDWdvb2dsZS5jb20ucGuCDWdvb2dsZS5jb20ucGyCDWdvb2dsZS5jb20u
cHKCDWdvb2dsZS5jb20ucHmCDWdvb2dsZS5jb20ucWGCDWdvb2dsZS5jb20ucnWC
DWdvb2dsZS5jb20uc2GCDWdvb2dsZS5jb20uc2KCDWdvb2dsZS5jb20uc2eCDWdv
b2dsZS5jb20uc2yCDWdvb2dsZS5jb20uc3aCDWdvb2dsZS5jb20udGqCDWdvb2ds
ZS5jb20udG6CDWdvb2dsZS5jb20udHKCDWdvb2dsZS5jb20udHeCDWdvb2dsZS5j
b20udWGCDWdvb2dsZS5jb20udXmCDWdvb2dsZS5jb20udmOCDWdvb2dsZS5jb20u
dmWCDWdvb2dsZS5jb20udm6CCWdvb2dsZS5jdoIJZ29vZ2xlLmN6gglnb29nbGUu
ZGWCCWdvb2dsZS5kaoIJZ29vZ2xlLmRrgglnb29nbGUuZG2CCWdvb2dsZS5keoIJ
Z29vZ2xlLmVlgglnb29nbGUuZXOCCmdvb2dsZS5ldXOCCWdvb2dsZS5maYIJZ29v
Z2xlLmZtgglnb29nbGUuZnKCCmdvb2dsZS5mcmyCCWdvb2dsZS5nYYIKZ29vZ2xl
LmdhbIIJZ29vZ2xlLmdlgglnb29nbGUuZ2eCCWdvb2dsZS5nbIIJZ29vZ2xlLmdt
gglnb29nbGUuZ3CCCWdvb2dsZS5ncoIJZ29vZ2xlLmd5gglnb29nbGUuaGuCCWdv
b2dsZS5oboIJZ29vZ2xlLmhygglnb29nbGUuaHSCCWdvb2dsZS5odYIJZ29vZ2xl
Lmllgglnb29nbGUuaW2CCWdvb2dsZS5pboILZ29vZ2xlLmluZm+CCWdvb2dsZS5p
cYIJZ29vZ2xlLmlygglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29vZ2xlLml0LmFv
gglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdvb2dsZS5qcIIJ
Z29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xlLmxhgglnb29n
bGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWCCWdvb2dsZS5s
doIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29vZ2xlLm1rggln
b29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUubXWCCWdvb2ds
ZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5qcIIKZ29vZ2xl
Lm5ldIIJZ29vZ2xlLm5ngglnb29nbGUubmyCCWdvb2dsZS5ub4IJZ29vZ2xlLm5y
gglnb29nbGUubnWCDWdvb2dsZS5vZmYuYWmCCWdvb2dsZS5wa4IJZ29vZ2xlLnBs
gglnb29nbGUucG6CCWdvb2dsZS5wc4IJZ29vZ2xlLnB0gglnb29nbGUucm+CCWdv
b2dsZS5yc4IJZ29vZ2xlLnJ1gglnb29nbGUucneCCWdvb2dsZS5zY4IJZ29vZ2xl
LnNlgglnb29nbGUuc2iCCWdvb2dsZS5zaYIJZ29vZ2xlLnNrgglnb29nbGUuc22C
CWdvb2dsZS5zboIJZ29vZ2xlLnNvgglnb29nbGUuc3KCCWdvb2dsZS5zdIIJZ29v
Z2xlLnRkggpnb29nbGUudGVsgglnb29nbGUudGeCCWdvb2dsZS50a4IJZ29vZ2xl
LnRsgglnb29nbGUudG2CCWdvb2dsZS50boIJZ29vZ2xlLnRvgglnb29nbGUudHSC
CWdvb2dsZS51YYIJZ29vZ2xlLnVzgglnb29nbGUudXqCCWdvb2dsZS52Z4IJZ29v
Z2xlLnZ1gglnb29nbGUud3OCEmdvb2dsZWNvbW1lcmNlLmNvbYILZ3N0YXRpYy5j
b22CCnVyY2hpbi5jb22CCHlvdXR1LmJlggt5b3V0dWJlLmNvbYIUeW91dHViZWVk
dWNhdGlvbi5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8v
cGtpLmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xp
ZW50czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBRV64RQzHpTPCAms0fQrZRz
vueE3zAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6
WoEvMCEGA1UdIAQaMBgwDAYKKwYBBAHWeQIFATAIBgZngQwBAgIwMAYDVR0fBCkw
JzAloCOgIYYfaHR0cDovL3BraS5nb29nbGUuY29tL0dJQUcyLmNybDANBgkqhkiG
9w0BAQsFAAOCAQEAX16cJNFG2m/ZrIzSqo/ktkNo3CPnXtsgmSQLwqYs2av0VlFz
EDfK61gS8+asgXsqlhDrsKM38Ehz1NkAGISHBFqzpUVzxjA+DVV/j+dU3xOSlOCN
jENuZzXLIGI10Zu7DDwBHPohAHJ5+UMyBnF7XBPFitOBu2ShZd9HFIeigXZwhsmV
DYTrITcGDlitMEa5ulZ9LhvJEat/6GcTg/Eshbf6YSpClAWlr8q7XNh9kWtdixv1
U7z+Uw2IzwoqzWzluFTQH0P/f1Jjn9JOILKDckPP0obk38z1MGKyEpHP1G2b5bDu
dPbx2gOKuwEeUlFKZIwBAxnNK360EQNE39b0Wg==
-----END CERTIFICATE-----
 1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2
   i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
-----BEGIN CERTIFICATE-----
MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT
MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG
EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy
bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP
VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv
h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE
ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ
EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC
DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7
qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD
VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov
L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig
JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ
MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+
3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI
hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI
Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X
Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm
X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40
fsg12A==
-----END CERTIFICATE-----
 2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
   i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
-----BEGIN CERTIFICATE-----
MIIDfTCCAuagAwIBAgIDErvmMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT
MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0
aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDIwNTIxMDQwMDAwWhcNMTgwODIxMDQwMDAw
WjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UE
AxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9m
OSm9BXiLnTjoBbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIu
T8rxh0PBFpVXLVDviS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6c
JmTM386DGXHKTubU1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmR
Cw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5asz
PeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo4HwMIHtMB8GA1UdIwQYMBaAFEjm
aPkr0rKV10fYIyAQTzOYkJ/UMB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrM
TjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjA6BgNVHR8EMzAxMC+g
LaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9jcmxzL3NlY3VyZWNhLmNybDBO
BgNVHSAERzBFMEMGBFUdIAAwOzA5BggrBgEFBQcCARYtaHR0cHM6Ly93d3cuZ2Vv
dHJ1c3QuY29tL3Jlc291cmNlcy9yZXBvc2l0b3J5MA0GCSqGSIb3DQEBBQUAA4GB
AHbhEm5OSxYShjAGsoEIz/AIx8dxfmbuwu3UOx//8PDITtZDOLC5MH0Y0FWDomrL
NhGc6Ehmo21/uBPUR/6LWlxz/K7ZGzIZOKuXNBSqltLroxwUCEm2u+WR74M26x1W
b8ravHNjkOR/ez4iyz0H7V84dJzjA1BOoa+Y7mHyhD8S
-----END CERTIFICATE-----
---
Server certificate
subject=/C=US/ST=California/L=Mountain View/O=Google Inc/CN=google.com
issuer=/C=US/O=Google Inc/CN=Google Internet Authority G2
---
No client certificate CA names sent
---
SSL handshake has read 10272 bytes and written 456 bytes
---
New, TLSv1/SSLv3, Cipher is AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : AES128-SHA
    Session-ID: A7E5F54D45DB7744E515B342802490A1D6748E9F94820BF708CDC4C6AD7A487D
    Session-ID-ctx: 
    Master-Key: 2D612A2B19DC6274481C68B9FEE2B274B27080CF1D9B60177EB0B45BDFDCF32D14D312B338DB3E16BEE8434123EE4009
    Key-Arg   : None
    Start Time: 1453595583
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---

Related Links for SSL and Cert Pinning on Android:

Tools for Decoding Certificates: