Understanding TLS Verification and Certificate Pinning
Hello, everyone 👋
In this article you will read and understand the importance of TLS Verification and Certificate Pinning.
TLS (Transport Layer Security) is an improved version of SSL (Secure Sockets Layer) protocol. It is a piece of software available almost in every device connected to network that provides a safe and secure communication between devices (computers, smart phones, TV, watches etc.). With TLS the data transmitted between devices are encrypted and can only be decrypted and used by device involved in communication. Example, when I type and enter kishoreconnect.com in browser, my browser (client) establishes an encrypted connection with kishoreconnect.com machine (server) using TLS and from that point forward any data sent and received between client and server are encrypted and can be used only by the participated devices.
Why does it even matter? What if I send the data unencrypted? Well, any data transmitted through internet/network can be intercepted and read, imagine a hacker has connected his machine to network and sniffing data, you will end-up sending all the data in plain text to him. Encrypted data sent using TLS can also be intercepted by a hacker, but of no use, he can't really decrypt the data.
As part of TLS connection establishing process, client needs to know the server it is talking to is legit and real machine that hosts kishoreconnect.com, because, any malicious computer in internet can intercept data and pretend to be the server. So, client asks server to prove it's identity. The server present it's certificate with identity information, and client verifies the certificate against trusted CA (Certificate Authority) store to determine if received certificate can be trusted, is called TLS Verification. If certificate cannot be verified or trusted, client terminates connection and warn user about the issue. It should appear like this in browser,
A certificate is an electronic document that has information about name of server (in this case, kishoreconnect.com), name of CA who issued certificate, a digital signature to identify CA and more. Certificate Authority (CA) is a trusted organization who is authorized to issue certificates. There are few publicly available trusted CAs like globalsign, verisign, digicert etc. A certificate is trustable only if it is issued by any of them. If you want to use a certificate in internet, preferably it should be from any of the publicly available trusted CAs for client to trust by default. For private/work network, we can setup our own CA and issue certificates for internal use.
In our example, for kishoreconnect.com web server, I buy a certificate from any of the authorized CAs by proving ownership of domain name (name of server), then I install the certificate in server to prove it's identify to clients that tries to connect. For client to recognize this certificate, it should have list of trusted CA certificates pre-installed in it, is called trust store. Generally, OS of client device takes care of installing and maintaining the trust store certs.
CA certificate is the publicly available certificate issued by CA for clients to use to verify server certificates. When client receives certificate from kishoreconnect.com, it runs through the certificate against it's list of CA certs in trust store to determine if certificate is issued by one of the trusted CAs, and so the client can believe server is real and not a bogus one (from a hacker). If client does not have the required CA certificate in it, it cannot verify the certificate received from kishoreconnect.com and so denies connection and alerts user that the certificate received cannot be verified and trusted.
There is an option available in any client to disable TLS verification, and we programmers always tempted to disable TLS verification in application we develop to keep things simple, but never do that! It is important that client verifies the TLS certificate before sending any data to server, else a malicious user can launch a Man-In-The-Middle (MITM) attack on you by pretending to be the real server.
Now, what if a hacker somehow fraudulently received a certificate from a trusted CA for kishoreconnect.com? He will be able to successfully disguise as real server of kishoreconnect.com even if the client does TLS verification! So, what now? read on :)
Certificate Pinning is a technique to fix certificates that are considered valid for a server instead of allowing any trusted certificates on the client side. The client stores (pinning) the fingerprint (hashed form of certificate) of trusted certificates of server, when server produces certificate, client does TLS Verification and checks if the certificate matches any of the pinned certificate. If a malicious user had fraudulently acquired certificate of a server, he would be able to pass TLS verification but not the check against pinned certificates.
A certificate issued by CA generally has expiration and will be renewed or changed after expiry, also CA may voluntarily invalidate an existing certificate and issue a new one if it finds any misuse. Now we know a certificate is tend to change and never be same always, it is quite challenging to take Certificate Pinning route as it may block client from connecting to server when the certificate is changed until client's pinned certificate copy is updated. To mitigate this, it is recommended to have a backup pin (fingerprint of another valid certificate for the same server), so that the client will still be able to connect when the certificate is changed. But if backup certificate is changed, we will have to update client's pinned certificate copy anyway.
Because of the challenge involved, Certificate Pinning is widely used among non-web applications like a mobile application. For mobile application, on the worst case it takes an app update to restore the connection between app and server. For web applications it is no longer recommended to use Certificate Pinning in favor of Certificate Transparency (CT). Certificate Transparency is an open framework designed to protect against and monitor for certificate misissuances. Newly issued certificates are logged to publicly run CT logs. The owner of web server can check and monitor CT if there is a fraudulently issued certificate of their server. In addition to that, modern browsers does check the CT logs by default for any misissuances.
How to configure Certificate Pinning?
All clients does provide an option for user to configure Certificate Pinning. In an Android Mobile Application we can configure as given below,
Create a network_security_config.xml file under res/xml folder
Provide certificate pinning configuration as given below
<network-security-config> <domain-config> <!--name of server the certificate fingerprints belong to--> <domain includeSubdomains="true">kishoreconnect.com</domain> <pin-set expiration="2018-01-01"> <!--fingerprint of certificate this android app should trust--> <pin digest="SHA-256">7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin> <!-- backup pin in case above certificate is changed--> <pin digest="SHA-256">fwza0LRMXouZHRC8Ei+4PyuldPDcf3UKgO/04cDM1oE=</pin> </pin-set> </domain-config> </network-security-config>
Include network_config_security.xml in AndroidManifest.xml file
<manifest ... > <application android:networkSecurityConfig="@xml/network_security_config"> </application> </manifest>
Now you know about TLS, TLS Verification, Certificate Pinning and the problem it solves. It is important to understand these, which helps in making acceptable decision when designing a secure solution.
Thanks for reading! Stay tuned 🙂